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

Christian Ebert blacktrash at gmx.net
Fri Oct 1 11:35:22 CDT 2010


# HG changeset patch
# User Christian Ebert <blacktrash at gmx.net>
# Date 1285950917 -7200
# Node ID 46da06a959cc929fe2a2bdc750ef42553b455714
# Parent  edf364870eb30b6f72cf01f0f90814409c314bf4
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
@@ -163,9 +163,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,
@@ -212,19 +212,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 = _shrinktext(data, self.re_kw.subn)
+                    data, found = _shrinktext(data, subn)
                 if found:
                     self.ui.note(msg % f)
                     self.repo.wwrite(f, data, mf.flags(f))
@@ -237,7 +238,7 @@
     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):
@@ -245,7 +246,7 @@
         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):
@@ -563,7 +564,7 @@
             if kwt.match(repo.dirstate.copied(f)):
                 data = repo.wread(f)
                 if not util.binary(data):
-                    data, found = _shrinktext(data, kwt.re_kw.subn)
+                    data, found = _shrinktext(data, kwt.re_kwexp.subn)
                     if found:
                         ui.note(_('overwriting %s shrinking keywords\n') % f)
                         repo.wwrite(f, data, wctx.flags(f))


More information about the Mercurial-devel mailing list