revset: add experimental ancestors/descendants relation subscript
The relation name is 'generations' now, which may be changed in future.
--- a/mercurial/revset.py Sat Jul 08 13:07:59 2017 +0900
+++ b/mercurial/revset.py Sat Jul 08 13:15:17 2017 +0900
@@ -155,7 +155,23 @@
raise error.ParseError(_("can't use a relation in this context"))
def relsubscriptset(repo, subset, x, y, z, order):
- raise error.ParseError(_("can't use a relation in this context"))
+ # this is pretty basic implementation of 'x#y[z]' operator, still
+ # experimental so undocumented. see the wiki for further ideas.
+ # https://www.mercurial-scm.org/wiki/RevsetOperatorPlan
+ rel = getsymbol(y)
+ n = getinteger(z, _("relation subscript must be an integer"))
+
+ # TODO: perhaps this should be a table of relation functions
+ if rel in ('g', 'generations'):
+ # TODO: support range, rewrite tests, and drop startdepth argument
+ # from ancestors() and descendants() predicates
+ if n <= 0:
+ n = -n
+ return _ancestors(repo, subset, x, startdepth=n, stopdepth=n + 1)
+ else:
+ return _descendants(repo, subset, x, startdepth=n, stopdepth=n + 1)
+
+ raise error.UnknownIdentifier(rel, ['generations'])
def subscriptset(repo, subset, x, y, order):
raise error.ParseError(_("can't use a subscript in this context"))
--- a/tests/test-revset.t Sat Jul 08 13:07:59 2017 +0900
+++ b/tests/test-revset.t Sat Jul 08 13:15:17 2017 +0900
@@ -512,8 +512,12 @@
('symbol', 'generations')
(negate
('symbol', '1'))))
- hg: parse error: can't use a relation in this context
- [255]
+ 9
+ 8
+ 7
+ 6
+ 5
+ 4
$ hg debugrevspec -p parsed --no-show-revs 'not public()#generations[0]'
* parsed:
@@ -524,8 +528,6 @@
None)
('symbol', 'generations')
('symbol', '0')))
- hg: parse error: can't use a relation in this context
- [255]
left-hand side of relation-subscript operator should be optimized recursively:
@@ -551,8 +553,6 @@
('symbol', 'generations')
('symbol', '0')
define)
- hg: parse error: can't use a relation in this context
- [255]
resolution of subscript and relation-subscript ternary operators:
@@ -572,7 +572,7 @@
('symbol', 'rel')
('symbol', '0')
define)
- hg: parse error: can't use a relation in this context
+ hg: parse error: unknown identifier: rel
[255]
$ hg debugrevspec -p analyzed '(tip#rel)[0]'
@@ -610,7 +610,7 @@
('symbol', 'rel1')
('symbol', '1')
define)
- hg: parse error: can't use a relation in this context
+ hg: parse error: unknown identifier: rel1
[255]
$ hg debugrevspec -p analyzed 'tip#rel0[0]#rel1[1]'
@@ -624,7 +624,7 @@
('symbol', 'rel1')
('symbol', '1')
define)
- hg: parse error: can't use a relation in this context
+ hg: parse error: unknown identifier: rel1
[255]
parse errors of relation, subscript and relation-subscript operators:
@@ -645,6 +645,13 @@
hg: parse error at 1: invalid token
[255]
+ $ hg debugrevspec '.#generations[a]'
+ hg: parse error: relation subscript must be an integer
+ [255]
+ $ hg debugrevspec '.#generations[1-2]'
+ hg: parse error: relation subscript must be an integer
+ [255]
+
parsed tree at stages:
$ hg debugrevspec -p all '()'
@@ -1180,6 +1187,27 @@
5
7
+test ancestors/descendants relation subscript:
+
+ $ log 'tip#generations[0]'
+ 9
+ $ log '.#generations[-1]'
+ 8
+ $ log '.#g[(-1)]'
+ 8
+
+ $ hg debugrevspec -p parsed 'roots(:)#g[2]'
+ * parsed:
+ (relsubscript
+ (func
+ ('symbol', 'roots')
+ (rangeall
+ None))
+ ('symbol', 'g')
+ ('symbol', '2'))
+ 2
+ 3
+
test author
$ log 'author(bob)'