[PATCH 1 of 3 gca-revset V2] revsets: add commonancestors revset
Sean Farley
sean at farley.io
Tue Jun 26 22:40:37 UTC 2018
# HG changeset patch
# User Sean Farley <sean at farley.io>
# Date 1529376114 25200
# Mon Jun 18 19:41:54 2018 -0700
# Branch gca-revset
# Node ID 33336034db436af9b15237bb87f82405eb039dfb
# Parent 2f5c622fcb739aed795c9ab51ea69c3b46436054
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.
diff --git a/mercurial/revset.py b/mercurial/revset.py
index 3746a22..14e53e9 100644
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -361,10 +361,27 @@ def ancestors(repo, subset, x):
raise error.ParseError(_("negative depth"))
stopdepth = n + 1
return _ancestors(repo, subset, args['set'],
startdepth=startdepth, stopdepth=stopdepth)
+ at 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()" but 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
+ h = heads(repo, subset, x)
+
+ commonrevs = repo.revs(" and ".join(["::%s"] * len(h), *h))
+
+ return subset & commonrevs
+
@predicate('_firstancestors', safe=True)
def _firstancestors(repo, subset, x):
# ``_firstancestors(set)``
# Like ``ancestors(set)`` but follows only the first parents.
return _ancestors(repo, subset, x, followfirst=True)
diff --git a/tests/test-revset.t b/tests/test-revset.t
index e2cde47..7872fc8 100644
--- a/tests/test-revset.t
+++ b/tests/test-revset.t
@@ -1039,10 +1039,32 @@ test ancestors
0
1
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)
$ log 'reverse(ancestors(9, depth=0))'
More information about the Mercurial-devel
mailing list