##// END OF EJS Templates
dispatch: protect against malicious 'hg serve --stdio' invocations (sec)...
dispatch: protect against malicious 'hg serve --stdio' invocations (sec) Some shared-ssh installations assume that 'hg serve --stdio' is a safe command to run for minimally trusted users. Unfortunately, the messy implementation of argument parsing here meant that trying to access a repo named '--debugger' would give the user a pdb prompt, thereby sidestepping any hoped-for sandboxing. Serving repositories over HTTP(S) is unaffected. We're not currently hardening any subcommands other than 'serve'. If your service exposes other commands to users with arbitrary repository names, it is imperative that you defend against repository names of '--debugger' and anything starting with '--config'. The read-only mode of hg-ssh stopped working because it provided its hook configuration to "hg serve --stdio" via --config parameter. This is banned for security reasons now. This patch switches it to directly call ui.setconfig(). If your custom hosting infrastructure relies on passing --config to "hg serve --stdio", you'll need to find a different way to get that configuration into Mercurial, either by using ui.setconfig() as hg-ssh does in this patch, or by placing an hgrc file someplace where Mercurial will read it. mitrandir@fb.com provided some extra fixes for the dispatch code and for hg-ssh in places that I overlooked.

File last commit:

r31331:1d7e8eb8 default
r32050:77eaf953 4.1.3 stable
Show More
keyword.py
760 lines | 27.7 KiB | text/x-python | PythonLexer
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 # keyword.py - $Keyword$ expansion for Mercurial
#
Christian Ebert
keyword: update copyright year
r23723 # Copyright 2007-2015 Christian Ebert <blacktrash@gmx.net>
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 #
Martin Geisler
updated license to be explicit about GPL version 2
r8225 # This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 #
# $Id$
#
Mads Kiilerich
fix trivial spelling errors
r17424 # Keyword expansion hack against the grain of a Distributed SCM
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 #
# There are many good reasons why this is not needed in a distributed
# SCM, still it may be useful in very small projects based on single
Martin Geisler
keyword: word-wrap help texts at 70 characters
r7993 # files (like LaTeX packages), that are mostly addressed to an
# audience not running a version control system.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 #
# For in-depth discussion refer to
Matt Mackall
urls: bulk-change primary website URLs
r26421 # <https://mercurial-scm.org/wiki/KeywordPlan>.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 #
# Keyword expansion is based on Mercurial's changeset template mappings.
#
# Binary files are not touched.
#
# Files to act upon/ignore are specified in the [keyword] section.
# Customized keyword template mappings in the [keywordmaps] section.
#
timeless
keyword: use single quotes in use warning
r29969 # Run 'hg help keyword' and 'hg kwdemo' to get info on configuration.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Cédric Duval
extensions: improve the consistency of synopses...
r8894 '''expand keywords in tracked files
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Martin Geisler
keyword: wrap docstrings at 70 characters
r9264 This extension expands RCS/CVS-like or self-customized $Keywords$ in
tracked text files selected by your configuration.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Martin Geisler
keyword: wrap docstrings at 70 characters
r9264 Keywords are only expanded in local repositories and not stored in the
change history. The mechanism can be regarded as a convenience for the
current user or for archive distribution.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Christian Ebert
keyword: explain file-wise expansion in help
r12203 Keywords expand to the changeset data pertaining to the latest change
relative to the working directory parent of each file.
Christian Ebert
keyword: offer svn-like default keywordmaps...
r11214 Configuration is done in the [keyword], [keywordset] and [keywordmaps]
sections of hgrc files.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Martin Geisler
commands: use minirst parser when displaying help
r9157 Example::
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
[keyword]
# expand keywords in every python file except those matching "x*"
**.py =
x* = ignore
Christian Ebert
keyword: offer svn-like default keywordmaps...
r11214 [keywordset]
# prefer svn- over cvs-like default keywordmaps
svn = True
Christian Ebert
Use more note admonitions in help texts
r12390 .. note::
Simon Heimberg
documentation: add an extra newline after note directive...
r19997
Christian Ebert
Use more note admonitions in help texts
r12390 The more specific you are in your filename patterns the less you
lose speed in huge repositories.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Martin Geisler
keyword: wrap docstrings at 70 characters
r9264 For [keywordmaps] template mapping and expansion demonstration and
Martin Geisler
Use hg role in help strings
r10973 control run :hg:`kwdemo`. See :hg:`help templates` for a list of
Christian Ebert
keyword: reference templating help, add utcdate filter example
r9307 available templates and filters.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Martin Geisler
keyword: convert a verbatim block to a field list
r13885 Three additional date template filters are provided:
Christian Ebert
keyword: add 2 svn-like date filters...
r11213
Martin Geisler
keyword: convert a verbatim block to a field list
r13885 :``utcdate``: "2006/09/18 15:13:13"
:``svnutcdate``: "2006-09-18 15:13:13Z"
:``svnisodate``: "2006-09-18 08:13:13 -700 (Mon, 18 Sep 2006)"
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Martin Geisler
Use hg role in help strings
r10973 The default template mappings (view with :hg:`kwdemo -d`) can be
replaced with customized keywords and templates. Again, run
Christian Ebert
keyword: s/config/configuration/ in help
r13025 :hg:`kwdemo` to control the results of your configuration changes.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Christian Ebert
keyword: update documentation for kwshrink...
r13270 Before changing/disabling active keywords, you must run :hg:`kwshrink`
to avoid storing expanded keywords in the change history.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Martin Geisler
keyword: wrap docstrings at 70 characters
r9264 To force expansion after enabling it, or a configuration change, run
Martin Geisler
Use hg role in help strings
r10973 :hg:`kwexpand`.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Martin Geisler
keyword: wrap docstrings at 70 characters
r9264 Expansions spanning more than one line and incremental expansions,
like CVS' $Log$, are not supported. A keyword template map "Log =
{desc}" expands to the first line of the changeset description.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 '''
Christian Ebert
keyword: use absolute_import
r28321
from __future__ import absolute_import
import os
import re
import tempfile
Yuya Nishihara
py3: move up symbol imports to enforce import-checker rules...
r29205 from mercurial.i18n import _
Christian Ebert
keyword: no expansion in web diffs...
r6072 from mercurial.hgweb import webcommands
Christian Ebert
keyword: use absolute_import
r28321
from mercurial import (
cmdutil,
commands,
context,
dispatch,
error,
extensions,
filelog,
localrepo,
match,
patch,
pathutil,
FUJIWARA Katsunori
keyword: use templatefilter to mark a function as template filter...
r28694 registrar,
Christian Ebert
keyword: use absolute_import
r28321 scmutil,
templatefilters,
util,
)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Martin Geisler
keyword: use cmdutil.command decorator
r14300 cmdtable = {}
command = cmdutil.command(cmdtable)
Augie Fackler
extensions: change magic "shipped with hg" string...
r29841 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
Augie Fackler
extensions: document that `testedwith = 'internal'` is special...
r25186 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
# be specifying the version(s) of Mercurial they are tested with, or
# leave the attribute unspecified.
Augie Fackler
extensions: change magic "shipped with hg" string...
r29841 testedwith = 'ships-with-hg-core'
Martin Geisler
keyword: use cmdutil.command decorator
r14300
Christian Ebert
keyword: nokwcommands, restricted string variables at top level...
r6024 # hg commands that do not act on keywords
Christian Ebert
keyword: support copy and rename...
r12626 nokwcommands = ('add addremove annotate bundle export grep incoming init log'
' outgoing push tip verify convert email glog')
Christian Ebert
keyword: nokwcommands, restricted string variables at top level...
r6024
Christian Ebert
keyword: detect restricted commands thru variable
r5961 # hg commands that trigger expansion only when writing to working dir,
# not when reading filelog, and unexpand when reading from working dir
FUJIWARA Katsunori
keyword: suppress keyword expansion while 'hg unshelve' for internal merge...
r21703 restricted = ('merge kwexpand kwshrink record qrecord resolve transplant'
FUJIWARA Katsunori
keyword: suppress keyword expansion while 'hg fetch' for internal merge...
r21708 ' unshelve rebase graft backout histedit fetch')
Christian Ebert
keyword: detect restricted commands thru variable
r5961
Christian Ebert
keyword: support extensions using dorecord, e.g. crecord...
r11168 # names of extensions using dorecord
recordextensions = 'record'
Christian Ebert
keyword: support (q)record...
r11045
Christian Ebert
keyword: colorize hg kwfiles output
r13078 colortable = {
'kwfiles.enabled': 'green bold',
Christian Ebert
keyword: make kwfiles show deleted files configured for expansion
r13079 'kwfiles.deleted': 'cyan bold underline',
Christian Ebert
keyword: colorize hg kwfiles output
r13078 'kwfiles.enabledunknown': 'green',
'kwfiles.ignored': 'bold',
'kwfiles.ignoredunknown': 'none'
}
FUJIWARA Katsunori
keyword: use templatefilter to mark a function as template filter...
r28694 templatefilter = registrar.templatefilter()
Christian Ebert
keyword: add 2 svn-like date filters...
r11213 # date like in cvs' $Date
FUJIWARA Katsunori
keyword: use templatefilter to mark a function as template filter...
r28694 @templatefilter('utcdate')
Patrick Mezard
templates: document missing keywords or filters...
r13592 def utcdate(text):
FUJIWARA Katsunori
keyword: use templatefilter to mark a function as template filter...
r28694 '''Date. Returns a UTC-date in this format: "2009/08/18 11:00:13".
Christian Ebert
keyword: docstrings for additional date filters
r13633 '''
Christian Ebert
templatefilters: avoid traceback caused by bogus date input (issue3344)...
r17755 return util.datestr((util.parsedate(text)[0], 0), '%Y/%m/%d %H:%M:%S')
Christian Ebert
keyword: add 2 svn-like date filters...
r11213 # date like in svn's $Date
FUJIWARA Katsunori
keyword: use templatefilter to mark a function as template filter...
r28694 @templatefilter('svnisodate')
Patrick Mezard
templates: document missing keywords or filters...
r13592 def svnisodate(text):
FUJIWARA Katsunori
keyword: use templatefilter to mark a function as template filter...
r28694 '''Date. Returns a date in this format: "2009-08-18 13:00:13
Christian Ebert
keyword: docstrings for additional date filters
r13633 +0200 (Tue, 18 Aug 2009)".
'''
Patrick Mezard
templates: document missing keywords or filters...
r13592 return util.datestr(text, '%Y-%m-%d %H:%M:%S %1%2 (%a, %d %b %Y)')
Christian Ebert
keyword: add 2 svn-like date filters...
r11213 # date like in svn's $Id
FUJIWARA Katsunori
keyword: use templatefilter to mark a function as template filter...
r28694 @templatefilter('svnutcdate')
Patrick Mezard
templates: document missing keywords or filters...
r13592 def svnutcdate(text):
FUJIWARA Katsunori
keyword: use templatefilter to mark a function as template filter...
r28694 '''Date. Returns a UTC-date in this format: "2009-08-18
Christian Ebert
keyword: docstrings for additional date filters
r13633 11:00:13Z".
'''
Christian Ebert
templatefilters: avoid traceback caused by bogus date input (issue3344)...
r17755 return util.datestr((util.parsedate(text)[0], 0), '%Y-%m-%d %H:%M:%SZ')
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Christian Ebert
keyword: make main class and hg command accessible...
r6115 # make keyword tools accessible
Christian Ebert
keyword: move collecting of [keyword] patterns to reposetup (issue2303)...
r11678 kwtools = {'templater': None, 'hgcmd': ''}
Christian Ebert
keyword: move expand/shrink decisions into kwtemplater...
r6114
Christian Ebert
keyword: offer svn-like default keywordmaps...
r11214 def _defaultkwmaps(ui):
'''Returns default keywordmaps according to keywordset configuration.'''
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 templates = {
'Revision': '{node|short}',
'Author': '{author|user}',
Christian Ebert
keyword: offer svn-like default keywordmaps...
r11214 }
kwsets = ({
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 'Date': '{date|utcdate}',
Christian Ebert
keyword: the CVS keyword is $RCSfile$, not $RCSFile$...
r9943 'RCSfile': '{file|basename},v',
timeless
keyword: clarify object of backwards compatibility
r9950 'RCSFile': '{file|basename},v', # kept for backwards compatibility
# with hg-keyword
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 'Source': '{root}/{file},v',
'Id': '{file|basename},v {node|short} {date|utcdate} {author|user}',
'Header': '{root}/{file},v {node|short} {date|utcdate} {author|user}',
Christian Ebert
keyword: offer svn-like default keywordmaps...
r11214 }, {
'Date': '{date|svnisodate}',
'Id': '{file|basename},v {node|short} {date|svnutcdate} {author|user}',
'LastChangedRevision': '{node|short}',
'LastChangedBy': '{author|user}',
'LastChangedDate': '{date|svnisodate}',
})
templates.update(kwsets[ui.configbool('keywordset', 'svn')])
return templates
Christian Ebert
keyword: refactor kwtemplater.overwrite()...
r12625 def _shrinktext(text, subfunc):
'''Helper for keyword expansion removal in text.
Depending on subfunc also returns number of substitutions.'''
return subfunc(r'$\1$', text)
Christian Ebert
keyword: code cleanup...
r12723 def _preselect(wstatus, changed):
Mads Kiilerich
fix trivial spelling errors
r17424 '''Retrieves modified and added files from a working directory state
Christian Ebert
keyword: code cleanup...
r12723 and returns the subset of each contained in given changed files
retrieved from a change context.'''
Martin von Zweigbergk
keyword: access status fields by name rather than index
r22918 modified = [f for f in wstatus.modified if f in changed]
added = [f for f in wstatus.added if f in changed]
Christian Ebert
keyword: code cleanup...
r12723 return modified, added
Christian Ebert
keyword: refactor kwtemplater.overwrite()...
r12625
Christian Ebert
keyword: offer svn-like default keywordmaps...
r11214 class kwtemplater(object):
'''
Sets up keyword templates, corresponding keyword regex, and
provides keyword substitution functions.
'''
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Christian Ebert
keyword: move collecting of [keyword] patterns to reposetup (issue2303)...
r11678 def __init__(self, ui, repo, inc, exc):
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 self.ui = ui
self.repo = repo
Christian Ebert
keyword: move collecting of [keyword] patterns to reposetup (issue2303)...
r11678 self.match = match.match(repo.root, '', [], inc, exc)
Christian Ebert
keyword: make main class and hg command accessible...
r6115 self.restrict = kwtools['hgcmd'] in restricted.split()
Christian Ebert
keyword: rename kwt.record attribute to kwt.postcommit...
r16809 self.postcommit = False
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
kwmaps = self.ui.configitems('keywordmaps')
if kwmaps: # override default templates
Yuya Nishihara
templater: remove noop calls of parsestring(s, quoted=False) (API)...
r24987 self.templates = dict(kwmaps)
Christian Ebert
keyword: offer svn-like default keywordmaps...
r11214 else:
self.templates = _defaultkwmaps(self.ui)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Christian Ebert
keyword: turn regexes and escaped keywords into a propertycache
r12926 @util.propertycache
def escape(self):
'''Returns bar-separated and escaped keywords.'''
return '|'.join(map(re.escape, self.templates.keys()))
@util.propertycache
def rekw(self):
'''Returns regex for unexpanded keywords.'''
return re.compile(r'\$(%s)\$' % self.escape)
@util.propertycache
def rekwexp(self):
'''Returns regex for expanded keywords.'''
return re.compile(r'\$(%s): [^$\n\r]*? \$' % self.escape)
Dirkjan Ochtman
keyword: be more efficient about ctx usage
r7375 def substitute(self, data, path, ctx, subfunc):
Christian Ebert
keyword: move expand/shrink decisions into kwtemplater...
r6114 '''Replaces keywords in data with expanded template.'''
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 def kwsub(mobj):
kw = mobj.group(1)
Matt Mackall
templating: make -T much more flexible...
r20668 ct = cmdutil.changeset_templater(self.ui, self.repo, False, None,
Matt Mackall
changeset_templater: remove use_template method
r20667 self.templates[kw], '', False)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 self.ui.pushbuffer()
Christian Ebert
keyword: make the templater a local variable...
r10894 ct.show(ctx, root=self.repo.root, file=path)
Christian Ebert
keyword: split line continuation in 2 steps (style)
r6023 ekw = templatefilters.firstline(self.ui.popbuffer())
return '$%s: %s $' % (kw, ekw)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 return subfunc(kwsub, data)
Christian Ebert
keyword: function to look up changectx for expansion...
r12920 def linkctx(self, path, fileid):
'''Similar to filelog.linkrev, but returns a changectx.'''
return self.repo.filectx(path, fileid=fileid).changectx()
Christian Ebert
keyword: move expand/shrink decisions into kwtemplater...
r6114 def expand(self, path, node, data):
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 '''Returns data with keywords expanded.'''
Christian Ebert
keyword: rename matcher() to match() mimicking changes in main
r8638 if not self.restrict and self.match(path) and not util.binary(data):
Christian Ebert
keyword: function to look up changectx for expansion...
r12920 ctx = self.linkctx(path, node)
Christian Ebert
keyword: turn regexes and escaped keywords into a propertycache
r12926 return self.substitute(data, path, ctx, self.rekw.sub)
Christian Ebert
keyword: move expand/shrink decisions into kwtemplater...
r6114 return data
Christian Ebert
keyword: make iskwfile() a weeding method in lieu of a boolean...
r12627 def iskwfile(self, cand, ctx):
'''Returns subset of candidates which are configured for keyword
Christian Ebert
keyword: correct grammar in iskwfile docstring
r15324 expansion but are not symbolic links.'''
Brodie Rao
cleanup: "not x in y" -> "x not in y"
r16686 return [f for f in cand if self.match(f) and 'l' not in ctx.flags(f)]
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Christian Ebert
keyword: enforce subn method via boolean switch...
r12685 def overwrite(self, ctx, candidates, lookup, expand, rekw=False):
Christian Ebert
keyword: move expand/shrink decisions into kwtemplater...
r6114 '''Overwrites selected files expanding/shrinking keywords.'''
Christian Ebert
keyword: rename kwt.record attribute to kwt.postcommit...
r16809 if self.restrict or lookup or self.postcommit: # exclude kw_copy
Christian Ebert
keyword: make iskwfile() a weeding method in lieu of a boolean...
r12627 candidates = self.iskwfile(candidates, ctx)
Christian Ebert
keyword: refactor kwtemplater.overwrite()...
r12625 if not candidates:
return
Christian Ebert
keyword: fix regressions introduced in d87f3ff904ba...
r12844 kwcmd = self.restrict and lookup # kwexpand/kwshrink
Christian Ebert
keyword: refactor kwtemplater.overwrite()...
r12625 if self.restrict or expand and lookup:
Christian Ebert
keyword: postpone manifest calculation in kwtemplater.overwrite...
r11350 mf = ctx.manifest()
Christian Ebert
keyword: avoid x = a and b or c
r15030 if self.restrict or rekw:
re_kw = self.rekw
else:
re_kw = self.rekwexp
if expand:
msg = _('overwriting %s expanding keywords\n')
else:
msg = _('overwriting %s shrinking keywords\n')
Christian Ebert
keyword: refactor kwtemplater.overwrite()...
r12625 for f in candidates:
if self.restrict:
data = self.repo.file(f).read(mf[f])
else:
data = self.repo.wread(f)
if util.binary(data):
continue
if expand:
Christian Ebert
keyword: handle resolve to either parent...
r23622 parents = ctx.parents()
Christian Ebert
keyword: refactor kwtemplater.overwrite()...
r12625 if lookup:
Christian Ebert
keyword: use wopener(..., atomictemp=True) to overwrite
r15083 ctx = self.linkctx(f, mf[f])
Christian Ebert
keyword: handle resolve to either parent...
r23622 elif self.restrict and len(parents) > 1:
# merge commit
# in case of conflict f is in modified state during
# merge, even if f does not differ from f in parent
for p in parents:
if f in p and not p[f].cmp(ctx[f]):
ctx = p[f].changectx()
break
Christian Ebert
keyword: use wopener(..., atomictemp=True) to overwrite
r15083 data, found = self.substitute(data, f, ctx, re_kw.subn)
Christian Ebert
keyword: refactor kwtemplater.overwrite()...
r12625 elif self.restrict:
Christian Ebert
keyword: turn regexes and escaped keywords into a propertycache
r12926 found = re_kw.search(data)
Christian Ebert
keyword: refactor kwtemplater.overwrite()...
r12625 else:
Christian Ebert
keyword: turn regexes and escaped keywords into a propertycache
r12926 data, found = _shrinktext(data, re_kw.subn)
Christian Ebert
keyword: refactor kwtemplater.overwrite()...
r12625 if found:
self.ui.note(msg % f)
Angel Ezquerra
localrepo: remove all external users of localrepo.wopener...
r23879 fp = self.repo.wvfs(f, "wb", atomictemp=True)
Christian Ebert
keyword: use wopener(..., atomictemp=True) to overwrite
r15083 fp.write(data)
fp.close()
Christian Ebert
keyword: fix regressions introduced in d87f3ff904ba...
r12844 if kwcmd:
Christian Ebert
keyword: refactor kwtemplater.overwrite()...
r12625 self.repo.dirstate.normal(f)
Christian Ebert
keyword: rename kwt.record attribute to kwt.postcommit...
r16809 elif self.postcommit:
Christian Ebert
keyword: refactor kwtemplater.overwrite()...
r12625 self.repo.dirstate.normallookup(f)
Christian Ebert
keyword: move expand/shrink decisions into kwtemplater...
r6114
def shrink(self, fname, text):
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 '''Returns text with all keyword substitutions removed.'''
Christian Ebert
keyword: rename matcher() to match() mimicking changes in main
r8638 if self.match(fname) and not util.binary(text):
Christian Ebert
keyword: turn regexes and escaped keywords into a propertycache
r12926 return _shrinktext(text, self.rekwexp.sub)
Christian Ebert
keyword: move expand/shrink decisions into kwtemplater...
r6114 return text
def shrinklines(self, fname, lines):
'''Returns lines with keyword substitutions removed.'''
Christian Ebert
keyword: rename matcher() to match() mimicking changes in main
r8638 if self.match(fname):
Christian Ebert
keyword: move expand/shrink decisions into kwtemplater...
r6114 text = ''.join(lines)
Bryan O'Sullivan
Get rid of reimplementations of util.binary
r6508 if not util.binary(text):
Christian Ebert
keyword: turn regexes and escaped keywords into a propertycache
r12926 return _shrinktext(text, self.rekwexp.sub).splitlines(True)
Christian Ebert
keyword: move expand/shrink decisions into kwtemplater...
r6114 return lines
def wread(self, fname, data):
'''If in restricted mode returns data read from wdir with
keyword substitutions removed.'''
Christian Ebert
keyword: avoid x = a and b or c
r15030 if self.restrict:
return self.shrink(fname, data)
return data
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
class kwfilelog(filelog.filelog):
'''
Subclass of filelog to hook into its read, add, cmp methods.
Keywords are "stored" unexpanded, and processed on reading.
'''
Christian Ebert
keyword: privatize remaining monkeypatches by moving them into reposetup...
r6503 def __init__(self, opener, kwt, path):
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 super(kwfilelog, self).__init__(opener, path)
Christian Ebert
keyword: privatize remaining monkeypatches by moving them into reposetup...
r6503 self.kwt = kwt
Christian Ebert
keyword: move expand/shrink decisions into kwtemplater...
r6114 self.path = path
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
def read(self, node):
'''Expands keywords when reading filelog.'''
data = super(kwfilelog, self).read(node)
Christian Ebert
keyword: disable expansion in kwfilelog.read() if file renamed in node...
r12628 if self.renamed(node):
return data
Christian Ebert
keyword: make main class and hg command accessible...
r6115 return self.kwt.expand(self.path, node, data)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
def add(self, text, meta, tr, link, p1=None, p2=None):
'''Removes keyword substitutions when adding to filelog.'''
Christian Ebert
keyword: make main class and hg command accessible...
r6115 text = self.kwt.shrink(self.path, text)
Christian Ebert
keyword: compact setting of optional arguments
r6504 return super(kwfilelog, self).add(text, meta, tr, link, p1, p2)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
def cmp(self, node, text):
'''Removes keyword substitutions for comparison.'''
Christian Ebert
keyword: make main class and hg command accessible...
r6115 text = self.kwt.shrink(self.path, text)
Christian Ebert
keyword: disable expansion in kwfilelog.read() if file renamed in node...
r12628 return super(kwfilelog, self).cmp(node, text)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Christian Ebert
keyword: reuse already present working contexts for match...
r14835 def _status(ui, repo, wctx, kwt, *pats, **opts):
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 '''Bails out if [keyword] configuration is not active.
Returns status of working directory.'''
Christian Ebert
keyword: make main class and hg command accessible...
r6115 if kwt:
Christian Ebert
keyword: reuse already present working contexts for match...
r14835 return repo.status(match=scmutil.match(wctx, pats, opts), clean=True,
Christian Ebert
keyword: remove deprecated options
r10652 unknown=opts.get('unknown') or opts.get('all'))
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 if ui.configitems('keyword'):
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('[keyword] patterns cannot match'))
raise error.Abort(_('no [keyword] patterns configured'))
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
def _kwfwrite(ui, repo, expand, *pats, **opts):
Christian Ebert
keyword: move expand/shrink decisions into kwtemplater...
r6114 '''Selects files and passes them to kwtemplater.overwrite.'''
Christian Ebert
keyword: pass context to kwtemplater.overwrite...
r11320 wctx = repo[None]
if len(wctx.parents()) > 1:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('outstanding uncommitted merge'))
Christian Ebert
keyword: make main class and hg command accessible...
r6115 kwt = kwtools['templater']
Bryan O'Sullivan
with: use context manager for wlock in _kwfwrite
r27815 with repo.wlock():
Christian Ebert
keyword: reuse already present working contexts for match...
r14835 status = _status(ui, repo, wctx, kwt, *pats, **opts)
Martin von Zweigbergk
keyword: access status fields by name rather than index
r22918 if status.modified or status.added or status.removed or status.deleted:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('outstanding uncommitted changes'))
Martin von Zweigbergk
keyword: access status fields by name rather than index
r22918 kwt.overwrite(wctx, status.clean, True, expand)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Martin Geisler
keyword: use cmdutil.command decorator
r14300 @command('kwdemo',
[('d', 'default', None, _('show default keyword template maps')),
('f', 'rcfile', '',
_('read maps from rcfile'), _('FILE'))],
Gregory Szorc
keyword: define optionalrepo in command decorator
r21776 _('hg kwdemo [-d] [-f RCFILE] [TEMPLATEMAP]...'),
optionalrepo=True)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 def demo(ui, repo, *args, **opts):
'''print [keywordmaps] configuration and an expansion example
Martin Geisler
keyword: word-wrap help texts at 70 characters
r7993 Show current, custom, or default keyword template maps and their
timeless
keyword: improve English
r8763 expansions.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Christian Ebert
keyword: refactor kwdemo and make output translatable...
r9281 Extend the current configuration by specifying maps as arguments
and using -f/--rcfile to source an external hgrc file.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Christian Ebert
keyword: refactor kwdemo and make output translatable...
r9281 Use -d/--default to disable current configuration.
Christian Ebert
keyword: reference templating help, add utcdate filter example
r9307
Martin Geisler
Use our custom hg reStructuredText role some more...
r11193 See :hg:`help templates` for information on templates and filters.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 '''
def demoitems(section, items):
ui.write('[%s]\n' % section)
Martin Geisler
keyword: sort demo output to ensure deterministic output
r9942 for k, v in sorted(items):
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 ui.write('%s = %s\n' % (k, v))
fn = 'demo.txt'
tmpdir = tempfile.mkdtemp('', 'kwdemo.')
Martin Geisler
expand "repo" to "repository" in help texts
r8027 ui.note(_('creating temporary repository at %s\n') % tmpdir)
Christian Ebert
keyword: avoid traceback when kwdemo is run outside a repo...
r29634 if repo is None:
baseui = ui
else:
baseui = repo.baseui
repo = localrepo.localrepository(baseui, tmpdir, True)
Mads Kiilerich
config: set a 'source' in most cases where config don't come from file but code...
r20790 ui.setconfig('keyword', fn, '', 'keyword')
Christian Ebert
keyword: inform user about current keywordset in kwdemo...
r13298 svn = ui.configbool('keywordset', 'svn')
# explicitly set keywordset for demo output
Mads Kiilerich
config: set a 'source' in most cases where config don't come from file but code...
r20790 ui.setconfig('keywordset', 'svn', svn, 'keyword')
Christian Ebert
keyword: refactor kwdemo and make output translatable...
r9281
uikwmaps = ui.configitems('keywordmaps')
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 if args or opts.get('rcfile'):
Christian Ebert
keyword: refactor kwdemo and make output translatable...
r9281 ui.status(_('\n\tconfiguration using custom keyword template maps\n'))
if uikwmaps:
ui.status(_('\textending current template maps\n'))
if opts.get('default') or not uikwmaps:
Christian Ebert
keyword: inform user about current keywordset in kwdemo...
r13298 if svn:
ui.status(_('\toverriding default svn keywordset\n'))
else:
ui.status(_('\toverriding default cvs keywordset\n'))
Christian Ebert
keyword: refactor kwdemo and make output translatable...
r9281 if opts.get('rcfile'):
ui.readconfig(opts.get('rcfile'))
if args:
# simulate hgrc parsing
Christian Ebert
keyword: compact writing of temporary kwdemo hgrc
r28458 rcmaps = '[keywordmaps]\n%s\n' % '\n'.join(args)
repo.vfs.write('hgrc', rcmaps)
Christian Ebert
keyword: refactor kwdemo and make output translatable...
r9281 ui.readconfig(repo.join('hgrc'))
kwmaps = dict(ui.configitems('keywordmaps'))
elif opts.get('default'):
Christian Ebert
keyword: inform user about current keywordset in kwdemo...
r13298 if svn:
ui.status(_('\n\tconfiguration using default svn keywordset\n'))
else:
ui.status(_('\n\tconfiguration using default cvs keywordset\n'))
Christian Ebert
keyword: offer svn-like default keywordmaps...
r11214 kwmaps = _defaultkwmaps(ui)
Christian Ebert
keyword: refactor kwdemo and make output translatable...
r9281 if uikwmaps:
ui.status(_('\tdisabling current template maps\n'))
Christian Ebert
keyword: improve use of dicts...
r5946 for k, v in kwmaps.iteritems():
Mads Kiilerich
config: set a 'source' in most cases where config don't come from file but code...
r20790 ui.setconfig('keywordmaps', k, v, 'keyword')
Christian Ebert
keyword: refactor kwdemo and make output translatable...
r9281 else:
ui.status(_('\n\tconfiguration using current keyword template maps\n'))
Christian Ebert
keyword: avoid x = a and b or c
r15030 if uikwmaps:
kwmaps = dict(uikwmaps)
else:
kwmaps = _defaultkwmaps(ui)
Christian Ebert
keyword: refactor kwdemo and make output translatable...
r9281
Christian Ebert
keyword: collect filename patterns, wrap dispatch._parse in uisetup...
r6502 uisetup(ui)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 reposetup(ui, repo)
FUJIWARA Katsunori
check-code: detect "missing _() in ui message" more exactly...
r29397 ui.write(('[extensions]\nkeyword =\n'))
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 demoitems('keyword', ui.configitems('keyword'))
Christian Ebert
keyword: inform user about current keywordset in kwdemo...
r13298 demoitems('keywordset', ui.configitems('keywordset'))
Christian Ebert
keyword: improve use of dicts...
r5946 demoitems('keywordmaps', kwmaps.iteritems())
Martin Geisler
keyword: sort demo output to ensure deterministic output
r9942 keywords = '$' + '$\n$'.join(sorted(kwmaps.keys())) + '$\n'
Angel Ezquerra
localrepo: remove all external users of localrepo.wopener...
r23879 repo.wvfs.write(fn, keywords)
Dirkjan Ochtman
move working dir/dirstate methods from localrepo to workingctx
r11303 repo[None].add([fn])
Christian Ebert
keyword: make kwdemo less verbose...
r10713 ui.note(_('\nkeywords written to %s:\n') % fn)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 ui.note(keywords)
Bryan O'Sullivan
with: use context manager for wlock in keyword demo
r27816 with repo.wlock():
Christian Ebert
keyword: wlock while setting branch in kwdemo
r20113 repo.dirstate.setbranch('demobranch')
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 for name, cmd in ui.configitems('hooks'):
if name.split('.', 1)[0].find('commit') > -1:
Mads Kiilerich
config: set a 'source' in most cases where config don't come from file but code...
r20790 repo.ui.setconfig('hooks', name, '', 'keyword')
Christian Ebert
keyword: mark improved demo commit message for translation...
r10499 msg = _('hg keyword configuration and expansion example')
Simon Heimberg
cleanup: Remove the only ever used skip-check-code pragma...
r20240 ui.note(("hg ci -m '%s'\n" % msg))
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 repo.commit(text=msg)
Christian Ebert
keyword: refactor kwdemo and make output translatable...
r9281 ui.status(_('\n\tkeywords expanded\n'))
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 ui.write(repo.wread(fn))
Christian Ebert
keyword: use wvfs.rmtree to remove kwdemo directory...
r24905 repo.wvfs.rmtree(repo.root)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Gregory Szorc
keyword: define inferrepo in command decorator
r21784 @command('kwexpand',
commands.walkopts,
_('hg kwexpand [OPTION]... [FILE]...'),
inferrepo=True)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 def expand(ui, repo, *pats, **opts):
timeless
keyword: improve English
r8763 '''expand keywords in the working directory
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Run after (re)enabling keyword expansion.
kwexpand refuses to run if given files contain local changes.
'''
# 3rd argument sets expansion to True
_kwfwrite(ui, repo, True, *pats, **opts)
Martin Geisler
keyword: use cmdutil.command decorator
r14300 @command('kwfiles',
[('A', 'all', None, _('show keyword status flags of all files')),
('i', 'ignore', None, _('show files excluded from expansion')),
('u', 'unknown', None, _('only show unknown (not tracked) files')),
] + commands.walkopts,
Gregory Szorc
keyword: define inferrepo in command decorator
r21784 _('hg kwfiles [OPTION]... [FILE]...'),
inferrepo=True)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 def files(ui, repo, *pats, **opts):
Christian Ebert
keyword: improve help for kwfiles...
r8957 '''show files configured for keyword expansion
Christian Ebert
keyword: improve help for kwfiles
r8950
Martin Geisler
keyword: wrap docstrings at 70 characters
r9264 List which files in the working directory are matched by the
[keyword] configuration patterns.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Martin Geisler
keyword: wrap docstrings at 70 characters
r9264 Useful to prevent inadvertent keyword expansion and to speed up
execution by including only files that are actual candidates for
expansion.
Christian Ebert
keyword: improve help for kwfiles
r8950
Martin Geisler
Use hg role in help strings
r10973 See :hg:`help keyword` on how to construct patterns both for
Martin Geisler
keyword: wrap docstrings at 70 characters
r9264 inclusion and exclusion of files.
Christian Ebert
keyword: improve help for kwfiles...
r8957
Christian Ebert
keyword: uppercase short option for kwfiles --all, like hg status -A...
r9494 With -A/--all and -v/--verbose the codes used to show the status
Martin Geisler
keyword: wrap docstrings at 70 characters
r9264 of files are::
Christian Ebert
keyword: reformat kwfiles help for minirst parser
r9195
K = keyword expansion candidate
Christian Ebert
keyword: kwfiles --unknown instead of --untracked...
r9491 k = keyword expansion candidate (not tracked)
Christian Ebert
keyword: reformat kwfiles help for minirst parser
r9195 I = ignored
Christian Ebert
keyword: kwfiles --unknown instead of --untracked...
r9491 i = ignored (not tracked)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 '''
Christian Ebert
keyword: make main class and hg command accessible...
r6115 kwt = kwtools['templater']
Christian Ebert
keyword: reuse already present working contexts for match...
r14835 wctx = repo[None]
status = _status(ui, repo, wctx, kwt, *pats, **opts)
Jordi Gutiérrez Hermoso
style: kill ersatz if-else ternary operators...
r24306 if pats:
cwd = repo.getcwd()
else:
cwd = ''
Christian Ebert
keyword: make kwfiles -u show untracked files only (like status)...
r9493 files = []
Christian Ebert
keyword: remove deprecated options
r10652 if not opts.get('unknown') or opts.get('all'):
Martin von Zweigbergk
keyword: access status fields by name rather than index
r22918 files = sorted(status.modified + status.added + status.clean)
Christian Ebert
keyword: make iskwfile() a weeding method in lieu of a boolean...
r12627 kwfiles = kwt.iskwfile(files, wctx)
Martin von Zweigbergk
keyword: access status fields by name rather than index
r22918 kwdeleted = kwt.iskwfile(status.deleted, wctx)
kwunknown = kwt.iskwfile(status.unknown, wctx)
Christian Ebert
keyword: make kwfiles -u show untracked files only (like status)...
r9493 if not opts.get('ignore') or opts.get('all'):
Christian Ebert
keyword: make kwfiles show deleted files configured for expansion
r13079 showfiles = kwfiles, kwdeleted, kwunknown
Christian Ebert
keyword: make kwfiles -u show untracked files only (like status)...
r9493 else:
Christian Ebert
keyword: make kwfiles show deleted files configured for expansion
r13079 showfiles = [], [], []
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 if opts.get('all') or opts.get('ignore'):
Christian Ebert
keyword: make kwfiles -u show untracked files only (like status)...
r9493 showfiles += ([f for f in files if f not in kwfiles],
Martin von Zweigbergk
keyword: access status fields by name rather than index
r22918 [f for f in status.unknown if f not in kwunknown])
Christian Ebert
keyword: make kwfiles show deleted files configured for expansion
r13079 kwlabels = 'enabled deleted enabledunknown ignored ignoredunknown'.split()
Christian Ebert
keyword: use ui.formatter for kwfiles output
r17057 kwstates = zip(kwlabels, 'K!kIi', showfiles)
fm = ui.formatter('kwfiles', opts)
fmt = '%.0s%s\n'
if opts.get('all') or ui.verbose:
fmt = '%s %s\n'
for kwstate, char, filenames in kwstates:
label = 'kwfiles.' + kwstate
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 for f in filenames:
Christian Ebert
keyword: use ui.formatter for kwfiles output
r17057 fm.startitem()
fm.write('kwstatus path', fmt, char,
repo.pathto(f, cwd), label=label)
fm.end()
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Gregory Szorc
keyword: define inferrepo in command decorator
r21784 @command('kwshrink',
commands.walkopts,
_('hg kwshrink [OPTION]... [FILE]...'),
inferrepo=True)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 def shrink(ui, repo, *pats, **opts):
timeless
keyword: improve English
r8763 '''revert expanded keywords in the working directory
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Christian Ebert
keyword: update documentation for kwshrink...
r13270 Must be run before changing/disabling active keywords.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
kwshrink refuses to run if given files contain local changes.
'''
# 3rd argument sets expansion to False
_kwfwrite(ui, repo, False, *pats, **opts)
Christian Ebert
keyword: collect filename patterns, wrap dispatch._parse in uisetup...
r6502 def uisetup(ui):
Christian Ebert
keyword: move collecting of [keyword] patterns to reposetup (issue2303)...
r11678 ''' Monkeypatches dispatch._parse to retrieve user command.'''
Christian Ebert
keyword: collect filename patterns, wrap dispatch._parse in uisetup...
r6502
Christian Ebert
keyword: move collecting of [keyword] patterns to reposetup (issue2303)...
r11678 def kwdispatch_parse(orig, ui, args):
'''Monkeypatch dispatch._parse to obtain running hg command.'''
cmd, func, args, options, cmdoptions = orig(ui, args)
kwtools['hgcmd'] = cmd
return cmd, func, args, options, cmdoptions
Christian Ebert
keyword: collect filename patterns, wrap dispatch._parse in uisetup...
r6502
Christian Ebert
keyword: move collecting of [keyword] patterns to reposetup (issue2303)...
r11678 extensions.wrapfunction(dispatch, '_parse', kwdispatch_parse)
Christian Ebert
keyword: collect filename patterns, wrap dispatch._parse in uisetup...
r6502
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 def reposetup(ui, repo):
'''Sets up repo as kwrepo for keyword substitution.
Overrides file method to return kwfilelog instead of filelog
if file matches user configuration.
Wraps commit to overwrite configured files with updated
keyword substitutions.
Christian Ebert
keyword: privatize remaining monkeypatches by moving them into reposetup...
r6503 Monkeypatches patch and webcommands.'''
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Matt Mackall
bundlerepo: reintroduce dirstate
r7853 try:
Christian Ebert
keyword: move collecting of [keyword] patterns to reposetup (issue2303)...
r11678 if (not repo.local() or kwtools['hgcmd'] in nokwcommands.split()
Matt Mackall
bundlerepo: reintroduce dirstate
r7853 or '.hg' in util.splitpath(repo.root)
or repo._url.startswith('bundle:')):
return
except AttributeError:
pass
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Christian Ebert
keyword: move collecting of [keyword] patterns to reposetup (issue2303)...
r11678 inc, exc = [], ['.hg*']
for pat, opt in ui.configitems('keyword'):
if opt != 'ignore':
inc.append(pat)
else:
exc.append(pat)
if not inc:
return
kwtools['templater'] = kwt = kwtemplater(ui, repo, inc, exc)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
class kwrepo(repo.__class__):
Christian Ebert
keyword: move expand/shrink decisions into kwtemplater...
r6114 def file(self, f):
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 if f[0] == '/':
f = f[1:]
Angel Ezquerra
localrepo: remove all external users of localrepo.sopener...
r23878 return kwfilelog(self.svfs, kwt, f)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Christian Ebert
keyword: support mq; handle (q)record more gracefully...
r5884 def wread(self, filename):
data = super(kwrepo, self).wread(filename)
Christian Ebert
keyword: make main class and hg command accessible...
r6115 return kwt.wread(filename, data)
Christian Ebert
keyword: support mq; handle (q)record more gracefully...
r5884
Christian Ebert
keyword: eliminate potential reference cycles from kwrepo...
r9096 def commit(self, *args, **opts):
Christian Ebert
keyword: make repo.commit use a custom commitctx wrapper...
r8996 # use custom commitctx for user commands
# other extensions can still wrap repo.commitctx directly
Christian Ebert
keyword: eliminate potential reference cycles from kwrepo...
r9096 self.commitctx = self.kwcommitctx
try:
Christian Ebert
keyword: do not postpone commit hooks...
r10495 return super(kwrepo, self).commit(*args, **opts)
Christian Ebert
keyword: eliminate potential reference cycles from kwrepo...
r9096 finally:
del self.commitctx
Christian Ebert
keyword: make repo.commit use a custom commitctx wrapper...
r8996
def kwcommitctx(self, ctx, error=False):
Christian Ebert
keyword: remove spurious locks, improve handling of wlock...
r10604 n = super(kwrepo, self).commitctx(ctx, error)
# no lock needed, only called from repo.commit() which already locks
Christian Ebert
keyword: rename kwt.record attribute to kwt.postcommit...
r16809 if not kwt.postcommit:
Christian Ebert
keyword: refactor kwtemplater.overwrite()...
r12625 restrict = kwt.restrict
kwt.restrict = True
Christian Ebert
keyword: pass context to kwtemplater.overwrite...
r11320 kwt.overwrite(self[n], sorted(ctx.added() + ctx.modified()),
Christian Ebert
keyword: refactor kwtemplater.overwrite()...
r12625 False, True)
kwt.restrict = restrict
Christian Ebert
keyword: remove spurious locks, improve handling of wlock...
r10604 return n
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Greg Ward
rollback: avoid unsafe rollback when not at tip (issue2998)...
r15183 def rollback(self, dryrun=False, force=False):
Christian Ebert
keyword: code cleanup...
r12723 wlock = self.wlock()
FUJIWARA Katsunori
keyword: make restrict mode False while updating files for rollback...
r26463 origrestrict = kwt.restrict
Christian Ebert
keyword: support rollback by restoring expansion to previous values...
r12498 try:
if not dryrun:
Christian Ebert
keyword: rename variable "cfiles" to "changed" for clarity
r12604 changed = self['.'].files()
Greg Ward
rollback: avoid unsafe rollback when not at tip (issue2998)...
r15183 ret = super(kwrepo, self).rollback(dryrun, force)
Christian Ebert
keyword: support rollback by restoring expansion to previous values...
r12498 if not dryrun:
ctx = self['.']
Martin von Zweigbergk
keyword: use parent of working copy as base for status...
r23079 modified, added = _preselect(ctx.status(), changed)
FUJIWARA Katsunori
keyword: make restrict mode False while updating files for rollback...
r26463 kwt.restrict = False
Christian Ebert
keyword: code cleanup...
r12723 kwt.overwrite(ctx, modified, True, True)
Christian Ebert
keyword: refactor kwtemplater.overwrite()...
r12625 kwt.overwrite(ctx, added, True, False)
Christian Ebert
keyword: support rollback by restoring expansion to previous values...
r12498 return ret
finally:
FUJIWARA Katsunori
keyword: make restrict mode False while updating files for rollback...
r26463 kwt.restrict = origrestrict
Christian Ebert
keyword: support rollback by restoring expansion to previous values...
r12498 wlock.release()
Christian Ebert
keyword: privatize remaining monkeypatches by moving them into reposetup...
r6503 # monkeypatches
Patrick Mezard
patch: generalize the use of patchmeta in applydiff()...
r14566 def kwpatchfile_init(orig, self, ui, gp, backend, store, eolmode=None):
Christian Ebert
keyword: privatize remaining monkeypatches by moving them into reposetup...
r6503 '''Monkeypatch/wrap patch.patchfile.__init__ to avoid
rejects or conflicts due to expanded keywords in working dir.'''
Patrick Mezard
patch: generalize the use of patchmeta in applydiff()...
r14566 orig(self, ui, gp, backend, store, eolmode)
Christian Ebert
keyword: privatize remaining monkeypatches by moving them into reposetup...
r6503 # shrink keywords read from working dir
self.lines = kwt.shrinklines(self.fname, self.lines)
Siddharth Agarwal
keyword: monkeypatch patch.diff more generically...
r24370 def kwdiff(orig, *args, **kwargs):
Christian Ebert
keyword: do not expand at all during diff...
r12497 '''Monkeypatch patch.diff to avoid expansion.'''
kwt.restrict = True
Siddharth Agarwal
keyword: monkeypatch patch.diff more generically...
r24370 return orig(*args, **kwargs)
Christian Ebert
keyword: disable expansion for annotate...
r6667
Matt Mackall
extensions: use new wrapper functions
r7216 def kwweb_skip(orig, web, req, tmpl):
'''Wraps webcommands.x turning off keyword expansion.'''
Christian Ebert
keyword: rename matcher() to match() mimicking changes in main
r8638 kwt.match = util.never
Matt Mackall
extensions: use new wrapper functions
r7216 return orig(web, req, tmpl)
Christian Ebert
keyword: privatize remaining monkeypatches by moving them into reposetup...
r6503
Christian Ebert
keyword: support commit --amend (issue3471)...
r16810 def kw_amend(orig, ui, repo, commitfunc, old, extra, pats, opts):
'''Wraps cmdutil.amend expanding keywords after amend.'''
Bryan O'Sullivan
with: use context manager for wlock in kw_amend
r27817 with repo.wlock():
Christian Ebert
keyword: support commit --amend (issue3471)...
r16810 kwt.postcommit = True
newid = orig(ui, repo, commitfunc, old, extra, pats, opts)
if newid != old.node():
ctx = repo[newid]
kwt.restrict = True
kwt.overwrite(ctx, ctx.files(), False, True)
kwt.restrict = False
return newid
Christian Ebert
keyword: support copy and rename...
r12626 def kw_copy(orig, ui, repo, pats, opts, rename=False):
'''Wraps cmdutil.copy so that copy/rename destinations do not
contain expanded keywords.
Christian Ebert
keyword: copy: when copied source is a symlink, follow it...
r13069 Note that the source of a regular file destination may also be a
symlink:
Christian Ebert
keyword: support copy and rename...
r12626 hg cp sym x -> x is symlink
cp sym x; hg cp -A sym x -> x is file (maybe expanded keywords)
Christian Ebert
keyword: copy: when copied source is a symlink, follow it...
r13069 For the latter we have to follow the symlink to find out whether its
target is configured for expansion and we therefore must unexpand the
keywords in the destination.'''
Bryan O'Sullivan
with: use context manager for wlock in kw_copy
r27818 with repo.wlock():
Christian Ebert
keyword: wlock cmdutil.copy wrapper...
r16811 orig(ui, repo, pats, opts, rename)
if opts.get('dry_run'):
return
wctx = repo[None]
cwd = repo.getcwd()
Christian Ebert
keyword: copy: when copied source is a symlink, follow it...
r13069
Christian Ebert
keyword: wlock cmdutil.copy wrapper...
r16811 def haskwsource(dest):
'''Returns true if dest is a regular file and configured for
expansion or a symlink which points to a file configured for
expansion. '''
source = repo.dirstate.copied(dest)
if 'l' in wctx.flags(source):
Augie Fackler
pathutil: tease out a new library to break an import cycle from canonpath use
r20033 source = pathutil.canonpath(repo.root, cwd,
Christian Ebert
keyword: wlock cmdutil.copy wrapper...
r16811 os.path.realpath(source))
return kwt.match(source)
Christian Ebert
keyword: copy: when copied source is a symlink, follow it...
r13069
Christian Ebert
keyword: wlock cmdutil.copy wrapper...
r16811 candidates = [f for f in repo.dirstate.copies() if
'l' not in wctx.flags(f) and haskwsource(f)]
kwt.overwrite(wctx, candidates, False, False)
Christian Ebert
keyword: support copy and rename...
r12626
Christian Ebert
keyword: support (q)record...
r11045 def kw_dorecord(orig, ui, repo, commitfunc, *pats, **opts):
'''Wraps record.dorecord expanding keywords after recording.'''
Bryan O'Sullivan
with: use context manager for wlock in kw_dorecord
r27819 with repo.wlock():
Christian Ebert
keyword: support (q)record...
r11045 # record returns 0 even when nothing has changed
# therefore compare nodes before and after
Christian Ebert
keyword: rename kwt.record attribute to kwt.postcommit...
r16809 kwt.postcommit = True
Christian Ebert
keyword: support (q)record...
r11045 ctx = repo['.']
Martin von Zweigbergk
keyword: use parent of working copy as base for status...
r23079 wstatus = ctx.status()
Christian Ebert
keyword: support (q)record...
r11045 ret = orig(ui, repo, commitfunc, *pats, **opts)
Christian Ebert
keyword: specific regular expressions depending on read mode...
r12630 recctx = repo['.']
if ctx != recctx:
Christian Ebert
keyword: code cleanup...
r12723 modified, added = _preselect(wstatus, recctx.files())
Christian Ebert
keyword: refactor kwtemplater.overwrite()...
r12625 kwt.restrict = False
Christian Ebert
keyword: enforce subn method via boolean switch...
r12685 kwt.overwrite(recctx, modified, False, True)
kwt.overwrite(recctx, added, False, True, True)
Christian Ebert
keyword: refactor kwtemplater.overwrite()...
r12625 kwt.restrict = True
Christian Ebert
keyword: support (q)record...
r11045 return ret
Nicolas Dumazet
filectx: use ctx.size comparisons to speed up ctx.cmp...
r12709 def kwfilectx_cmp(orig, self, fctx):
Christian Ebert
keyword: handle filectx _customcmp...
r30326 if fctx._customcmp:
return fctx.cmp(self)
Nicolas Dumazet
filectx: use ctx.size comparisons to speed up ctx.cmp...
r12709 # keyword affects data size, comparing wdir and filelog size does
# not make sense
Christian Ebert
keyword: replace use of _filerev with _filenode...
r29055 if (fctx._filenode is None and
Christian Ebert
keyword: only use expensive fctx.cmp when needed...
r12732 (self._repo._encodefilterpats or
Brodie Rao
cleanup: "not x in y" -> "x not in y"
r16686 kwt.match(fctx.path()) and 'l' not in fctx.flags() or
Christian Ebert
keyword: update filectx.cmp monkeypatch to handle '\1\n' at start of file...
r15871 self.size() - 4 == fctx.size()) or
Christian Ebert
keyword: only use expensive fctx.cmp when needed...
r12732 self.size() == fctx.size()):
return self._filelog.cmp(self._filenode, fctx.data())
return True
Nicolas Dumazet
filectx: use ctx.size comparisons to speed up ctx.cmp...
r12709 extensions.wrapfunction(context.filectx, 'cmp', kwfilectx_cmp)
Matt Mackall
extensions: use new wrapper functions
r7216 extensions.wrapfunction(patch.patchfile, '__init__', kwpatchfile_init)
Siddharth Agarwal
keyword: rename kw_diff to kwdiff in keeping with Mercurial style rules...
r24369 extensions.wrapfunction(patch, 'diff', kwdiff)
Christian Ebert
keyword: support commit --amend (issue3471)...
r16810 extensions.wrapfunction(cmdutil, 'amend', kw_amend)
Christian Ebert
keyword: support copy and rename...
r12626 extensions.wrapfunction(cmdutil, 'copy', kw_copy)
Laurent Charignon
record: move dorecord from record to cmdutil...
r24272 extensions.wrapfunction(cmdutil, 'dorecord', kw_dorecord)
Matt Mackall
extensions: use new wrapper functions
r7216 for c in 'annotate changeset rev filediff diff'.split():
extensions.wrapfunction(webcommands, c, kwweb_skip)
Christian Ebert
keyword: move repo.__class__ assignment out of monkeypatch context...
r13299 repo.__class__ = kwrepo