[PATCH] revsets: makes follow() supports file patterns (issue4757)

liscju piotr.listkiewicz at gmail.com
Sun Aug 23 09:52:21 UTC 2015


# HG changeset patch
# User liscju <piotr.listkiewicz at gmail.com>
# Date 1440083972 -7200
#      Thu Aug 20 17:19:32 2015 +0200
# Branch bug4757#followRevset
# Node ID 4bd021d45c66503b7d6a01ebcc1711722e10f264
# Parent  d9d3d49c4cf77049d12920980e91bf8e4a4ecda2
revsets: makes follow() supports file patterns (issue4757)

Before this patch, follow only supports full, exact filenames.
This patch makes follow argument to be treated like file
pattern same way like log treats their arguments.

It preserves current behaviour of follow() matching files
against the repository root, not current working directory.

diff -r d9d3d49c4cf7 -r 4bd021d45c66 mercurial/revset.py
--- a/mercurial/revset.py	Tue Aug 18 18:38:56 2015 -0500
+++ b/mercurial/revset.py	Thu Aug 20 17:19:32 2015 +0200
@@ -1037,34 +1037,36 @@
     return limit(repo, subset, x)
 
 def _follow(repo, subset, x, name, followfirst=False):
-    l = getargs(x, 0, 1, _("%s takes no arguments or a filename") % name)
+    l = getargs(x, 0, 1, _("%s takes no arguments or a pattern") % name)
     c = repo['.']
     if l:
-        x = getstring(l[0], _("%s expected a filename") % name)
-        if x in c:
-            cx = c[x]
-            s = set(ctx.rev() for ctx in cx.ancestors(followfirst=followfirst))
-            # include the revision responsible for the most recent version
-            s.add(cx.introrev())
-        else:
-            return baseset()
+        x = getstring(l[0], _("%s expected a pattern") % name)
+        wctx = repo[None]
+        matcher = matchmod.match(repo.root, '', [x], ctx=wctx)
+
+        s = set()
+        for fname in c:
+            if matcher(fname):
+                fctx = c[fname]
+                s = s.union(set(c.rev() for c in fctx.ancestors(followfirst)))
+                s.add(fctx.introrev())
     else:
         s = _revancestors(repo, baseset([c.rev()]), followfirst)
 
     return subset & s
 
 def follow(repo, subset, x):
-    """``follow([file])``
+    """``follow([pattern])``
     An alias for ``::.`` (ancestors of the working directory's first parent).
-    If a filename is specified, the history of the given file is followed,
-    including copies.
+    If pattern is specified, the histories of files matching given
+    pattern is followed, including copies.
     """
     return _follow(repo, subset, x, 'follow')
 
 def _followfirst(repo, subset, x):
-    # ``followfirst([file])``
-    # Like ``follow([file])`` but follows only the first parent of
-    # every revision or file revision.
+    # ``followfirst([pattern])``
+    # Like ``follow([pattern])`` but follows only the first parent of
+    # every revisions or files revisions.
     return _follow(repo, subset, x, '_followfirst', followfirst=True)
 
 def getall(repo, subset, x):
diff -r d9d3d49c4cf7 -r 4bd021d45c66 tests/test-log.t
--- a/tests/test-log.t	Tue Aug 18 18:38:56 2015 -0500
+++ b/tests/test-log.t	Thu Aug 20 17:19:32 2015 +0200
@@ -646,7 +646,26 @@
   summary:     base
   
 
+log -r follow('b*')
 
+  $ hg log -r "follow('b*')"
+  changeset:   0:67e992f2c4f3
+  user:        test
+  date:        Thu Jan 01 00:00:01 1970 +0000
+  summary:     base
+  
+  changeset:   1:3d5bf5654eda
+  user:        test
+  date:        Thu Jan 01 00:00:01 1970 +0000
+  summary:     r1
+  
+  changeset:   3:e62f78d544b4
+  tag:         tip
+  parent:      1:3d5bf5654eda
+  user:        test
+  date:        Thu Jan 01 00:00:01 1970 +0000
+  summary:     b1
+  
 log -f -r '1 + 4'
 
   $ hg up -C 0
@@ -673,6 +692,16 @@
   date:        Thu Jan 01 00:00:01 1970 +0000
   summary:     base
   
+log -r "follow('set:grep(b2)')"
+
+  $ hg log -r "follow('set:grep(b2)')"
+  changeset:   4:ddb82e70d1a1
+  tag:         tip
+  parent:      0:67e992f2c4f3
+  user:        test
+  date:        Thu Jan 01 00:00:01 1970 +0000
+  summary:     b2
+  
 log -f -r null
 
   $ hg log -f -r null


More information about the Mercurial-devel mailing list