[PATCH 5 of 5] keyword: specific regular expressions depending on read mode

Christian Ebert blacktrash at gmx.net
Wed Sep 29 19:19:55 CDT 2010


# HG changeset patch
# User Christian Ebert <blacktrash at gmx.net>
# Date 1285805906 -7200
# Node ID e085f9ccf6a5c28e8191b005aff2c887d802b69a
# Parent  fe49a71ae1c400482cccc081f1f2090259a806d5
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.

This way we finally also forbid sequences like $Id:  $ being treated
as keywords.

diff --git a/hgext/keyword.py b/hgext/keyword.py
--- a/hgext/keyword.py
+++ b/hgext/keyword.py
@@ -158,9 +158,9 @@
                                   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,
@@ -207,19 +207,20 @@
             for f in candidates:
                 if self.restrict:           # commit, kwexpand, kwshrink
                     data = self.repo.file(f).read(mf[f])
+                    subn = self.re_kw.subn
                 else:
                     data = self.repo.wread(f)
+                    subn = self.re_kwexp.subn
                 if util.binary(data):
                     continue
                 if expand:
                     if iswctx:
                         ctx = self.repo.filectx(f, fileid=mf[f]).changectx()
-                    data, found = self.substitute(data, f, ctx,
-                                                  self.re_kw.subn)
+                    data, found = self.substitute(data, f, ctx, subn)
                 elif self.restrict:
                     found = self.re_kw.search(data)
                 else:
-                    data, found = self.re_kw.subn(r'$\1$', data)
+                    data, found = subn(r'$\1$', data)
                 if found:
                     self.ui.note(msg % f)
                     self.repo.wwrite(f, data, mf.flags(f))
@@ -231,7 +232,7 @@
 
     def shrinktext(self, text):
         '''Unconditionally removes all keyword substitutions from text.'''
-        return self.re_kw.sub(r'$\1$', text)
+        return self.re_kwexp.sub(r'$\1$', text)
 
     def shrink(self, fname, text):
         '''Returns text with all keyword substitutions removed.'''
@@ -568,8 +569,8 @@
             if not util.binary(data):
                 diffmatch = match.match(repo, '', [f], exact=True)
                 for chunk in patch.diff(repo, match=diffmatch, opts=diffopts):
-                    if kwt.re_kw.search(chunk):
-                        data = kwt.re_kw.sub(r'$\1$', data)
+                    if kwt.re_kwexp.search(chunk):
+                        data = kwt.re_kwexp.sub(r'$\1$', data)
                         ui.note(_('overwriting %s shrinking keywords\n') % f)
                         repo.wwrite(f, data, wctx.flags(f))
                         break


More information about the Mercurial-devel mailing list