keyword: specific regular expressions depending on read mode

More safeguarding against accidental (un)expansion:

Reading filelog: act only on \$(kw1|kw2|..)\$ as keywords are always
                 stored unexpanded.
Reading wdir:    act only on \$(kw1|kw2|..): [^$\n\r]*? \$ as we only
                 are interested in expanded keywords in this situation.
                 Note: we cannot use ..): [^$\n\r]+? \$ because e.g.
                 the {branch} template might be empty.

hg record is a special case as we read from the working directory and
need one regex each for modified and added files. Therefore test
recording an added file.

This way we finally also forbid sequences like $Id:  $ being treated
as keywords.
This commit is contained in:
Christian Ebert 2010-10-08 18:39:46 +01:00
parent f377c1b282
commit 924a741c44
2 changed files with 36 additions and 13 deletions

View File

@ -163,9 +163,9 @@ class kwtemplater(object):
for k, v in kwmaps)
else:
self.templates = _defaultkwmaps(self.ui)
escaped = map(re.escape, self.templates.keys())
kwpat = r'\$(%s)(: [^$\n\r]*? )??\$' % '|'.join(escaped)
self.re_kw = re.compile(kwpat)
escaped = '|'.join(map(re.escape, self.templates.keys()))
self.re_kw = re.compile(r'\$(%s)\$' % escaped)
self.re_kwexp = re.compile(r'\$(%s): [^$\n\r]*? \$' % escaped)
templatefilters.filters.update({'utcdate': utcdate,
'svnisodate': svnisodate,
@ -196,7 +196,7 @@ class kwtemplater(object):
expansion are not symbolic links.'''
return [f for f in cand if self.match(f) and not 'l' in ctx.flags(f)]
def overwrite(self, ctx, candidates, lookup, expand):
def overwrite(self, ctx, candidates, lookup, expand, recsubn=None):
'''Overwrites selected files expanding/shrinking keywords.'''
if self.restrict or lookup: # exclude kw_copy
candidates = self.iskwfile(candidates, ctx)
@ -206,6 +206,8 @@ class kwtemplater(object):
if self.restrict or expand and lookup:
mf = ctx.manifest()
fctx = ctx
subn = (self.restrict and self.re_kw.subn or
recsubn or self.re_kwexp.subn)
msg = (expand and _('overwriting %s expanding keywords\n')
or _('overwriting %s shrinking keywords\n'))
for f in candidates:
@ -218,11 +220,11 @@ class kwtemplater(object):
if expand:
if lookup:
fctx = self.repo.filectx(f, fileid=mf[f]).changectx()
data, found = self.substitute(data, f, fctx, self.re_kw.subn)
data, found = self.substitute(data, f, fctx, subn)
elif self.restrict:
found = self.re_kw.search(data)
else:
data, found = _shrinktext(data, self.re_kw.subn)
data, found = _shrinktext(data, subn)
if found:
self.ui.note(msg % f)
self.repo.wwrite(f, data, ctx.flags(f))
@ -234,7 +236,7 @@ class kwtemplater(object):
def shrink(self, fname, text):
'''Returns text with all keyword substitutions removed.'''
if self.match(fname) and not util.binary(text):
return _shrinktext(text, self.re_kw.sub)
return _shrinktext(text, self.re_kwexp.sub)
return text
def shrinklines(self, fname, lines):
@ -242,7 +244,7 @@ class kwtemplater(object):
if self.match(fname):
text = ''.join(lines)
if not util.binary(text):
return _shrinktext(text, self.re_kw.sub).splitlines(True)
return _shrinktext(text, self.re_kwexp.sub).splitlines(True)
return lines
def wread(self, fname, data):
@ -569,12 +571,15 @@ def reposetup(ui, repo):
# record returns 0 even when nothing has changed
# therefore compare nodes before and after
ctx = repo['.']
modified, added = repo[None].status()[:2]
ret = orig(ui, repo, commitfunc, *pats, **opts)
recordctx = repo['.']
if ctx != recordctx:
candidates = [f for f in recordctx.files() if f in recordctx]
recctx = repo['.']
if ctx != recctx:
modified = [f for f in modified if f in recctx]
added = [f for f in added if f in recctx]
kwt.restrict = False
kwt.overwrite(recordctx, candidates, False, True)
kwt.overwrite(recctx, modified, False, True, kwt.re_kwexp.subn)
kwt.overwrite(recctx, added, False, True, kwt.re_kw.subn)
kwt.restrict = True
return ret
finally:

View File

@ -373,7 +373,6 @@ File a should be clean
$ hg status -A a
C a
$ rm msg
rollback and revert expansion
@ -418,6 +417,25 @@ Only z should be overwritten
$ hg update -C
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
record added file
$ echo '$Id$' > r
$ hg add r
$ hg -v record -l msg -d '1 12' r<<EOF
> y
> EOF
diff --git a/r b/r
new file mode 100644
examine changes to 'r'? [Ynsfdaq?]
r
committed changeset 3:899491280810
overwriting r expanding keywords
$ hg --verbose rollback
rolling back to revision 2 (undo commit)
overwriting r shrinking keywords
$ hg forget r
$ rm msg r
Test patch queue repo
$ hg init --mq