revset: change ancestor to accept 0 or more arguments (
issue3750)
Change ancestor to accept 0 or more arguments. The greatest common ancestor of a
single changeset is that changeset. If passed no arguments, the empty list is
returned.
--- a/mercurial/revset.py Fri Feb 01 15:48:33 2013 -0600
+++ b/mercurial/revset.py Mon Jan 28 12:19:21 2013 -0800
@@ -277,20 +277,32 @@
return checkstatus(repo, subset, pat, 1)
def ancestor(repo, subset, x):
- """``ancestor(single, single)``
- Greatest common ancestor of the two changesets.
+ """``ancestor(*changeset)``
+ Greatest common ancestor of the changesets.
+
+ Accepts 0 or more changesets.
+ Will return empty list when passed no args.
+ Greatest common ancestor of a single changeset is that changeset.
"""
# i18n: "ancestor" is a keyword
- l = getargs(x, 2, 2, _("ancestor requires two arguments"))
- r = list(repo)
- a = getset(repo, r, l[0])
- b = getset(repo, r, l[1])
- if len(a) != 1 or len(b) != 1:
- # i18n: "ancestor" is a keyword
- raise error.ParseError(_("ancestor arguments must be single revisions"))
- an = [repo[a[0]].ancestor(repo[b[0]]).rev()]
+ l = getlist(x)
+ rl = list(repo)
+ anc = None
- return [r for r in an if r in subset]
+ # (getset(repo, rl, i) for i in l) generates a list of lists
+ rev = repo.changelog.rev
+ ancestor = repo.changelog.ancestor
+ node = repo.changelog.node
+ for revs in (getset(repo, rl, i) for i in l):
+ for r in revs:
+ if anc is None:
+ anc = r
+ else:
+ anc = rev(ancestor(node(anc), node(r)))
+
+ if anc is not None and anc in subset:
+ return [anc]
+ return []
def _ancestors(repo, subset, x, followfirst=False):
args = getset(repo, list(repo), x)
--- a/tests/test-revset.t Fri Feb 01 15:48:33 2013 -0600
+++ b/tests/test-revset.t Mon Jan 28 12:19:21 2013 -0800
@@ -218,17 +218,29 @@
$ log 'date(2005) and 1::'
4
+ancestor can accept 0 or more arguments
+
+ $ log 'ancestor()'
$ log 'ancestor(1)'
- hg: parse error: ancestor requires two arguments
- [255]
+ 1
$ log 'ancestor(4,5)'
1
$ log 'ancestor(4,5) and 4'
+ $ log 'ancestor(0,0,1,3)'
+ 0
+ $ log 'ancestor(3,1,5,3,5,1)'
+ 1
+ $ log 'ancestor(0,1,3,5)'
+ 0
+ $ log 'ancestor(1,2,3,4,5)'
+ 1
$ log 'ancestors(5)'
0
1
3
5
+ $ log 'ancestor(ancestors(5))'
+ 0
$ log 'author(bob)'
2
$ log 'author("re:bob|test")'