revsets: add commonancestors revset
authorSean Farley <sean@farley.io>
Mon, 18 Jun 2018 19:41:54 -0700
changeset 38624 5460926352ee
parent 38623 92c845c097aa
child 38625 52f19a840543
revsets: add commonancestors revset This is a method to reproduce "::x and ::y" such that a set can be sent in. For instance, it'd be convenient to have "::heads()" work like this but that already means "::x + ::y + ..." for each element in the "heads()" set. Therefore, we add the "commonancestors" method to mean "::x and ::y ..." for each head in the given set.
mercurial/revset.py
tests/test-revset.t
--- a/mercurial/revset.py	Mon Jul 09 10:07:20 2018 -0400
+++ b/mercurial/revset.py	Mon Jun 18 19:41:54 2018 -0700
@@ -608,6 +608,22 @@
     return subset.filter(lambda r: repo[r].closesbranch(),
                          condrepr='<branch closed>')
 
+@predicate('commonancestors(set)', safe=True)
+def commonancestors(repo, subset, x):
+    """Returns all common ancestors of the set.
+
+    This method is for calculating "::x and ::y" (i.e. all the ancestors that
+    are common to both x and y) in an easy and optimized way. We can't quite
+    use "::head()" because that revset returns "::x + ::y + ..." for each head
+    in the repo (whereas we want "::x *and* ::y").
+
+    """
+    # only wants the heads of the set passed in
+    for r in heads(repo, fullreposet(repo), x, defineorder):
+        subset &= dagop.revancestors(repo, baseset([r]))
+
+    return subset
+
 @predicate('contains(pattern)', weight=100)
 def contains(repo, subset, x):
     """The revision's manifest contains a file matching pattern (but might not
--- a/tests/test-revset.t	Mon Jul 09 10:07:20 2018 -0400
+++ b/tests/test-revset.t	Mon Jun 18 19:41:54 2018 -0700
@@ -1041,6 +1041,28 @@
   2
   3
 
+test common ancestors
+
+  $ hg log -T '{rev}\n' -r 'commonancestors(7 + 9)'
+  0
+  1
+  2
+  4
+
+  $ hg log -T '{rev}\n' -r 'commonancestors(head())'
+  0
+  1
+  2
+  4
+
+  $ hg log -T '{rev}\n' -r 'commonancestors(9)'
+  0
+  1
+  2
+  4
+  8
+  9
+
 test ancestors with depth limit
 
  (depth=0 selects the node itself)