From patchwork Wed Jan 16 10:29:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [V2] revset: support ranges in #generations relation From: Anton Shestakov X-Patchwork-Id: 37787 Message-Id: <039a0d0d913afac1464b.1547634597@neuro> To: mercurial-devel@mercurial-scm.org Date: Wed, 16 Jan 2019 18:29:57 +0800 # HG changeset patch # User Anton Shestakov # Date 1547564229 -28800 # Tue Jan 15 22:57:09 2019 +0800 # Node ID 039a0d0d913afac1464bfc1ea8a49b22e803b081 # Parent 8aca89a694d4bd7d25877b3652fb83e187ea1802 revset: support ranges in #generations relation diff --git a/mercurial/revset.py b/mercurial/revset.py --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -225,24 +225,54 @@ def notset(repo, subset, x, order): def relationset(repo, subset, x, y, order): raise error.ParseError(_("can't use a relation in this context")) -def generationsrel(repo, subset, x, rel, n, order): - # 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) +def generationsrel(repo, subset, x, rel, a, b, order): + # TODO: rewrite tests, and drop startdepth argument from ancestors() and + # descendants() predicates + if a < 0 or a is None: + if b >= 0 or b is None: + startdepth = 1 + else: + startdepth = -b + 1 + if a is None: + stopdepth = None + else: + stopdepth = -a + 1 + aset = _ancestors(repo, subset, x, False, startdepth, stopdepth) else: - return _descendants(repo, subset, x, startdepth=n, stopdepth=n + 1) + aset = baseset() + + if b >= 0 or b is None: + if a < 0 or a is None: + startdepth = 0 + else: + startdepth = a + stopdepth = b + dset = _descendants(repo, subset, x, False, startdepth, stopdepth) + else: + dset = baseset() + + return aset + dset def relsubscriptset(repo, subset, x, y, z, order): # 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")) + try: + a, b = getrange(z, '') + except error.ParseError: + a = getinteger(z, _("relation subscript must be an integer")) + b = a + 1 + else: + def getbound(i): + if i is None: + return None + msg = _("relation subscript bounds must be integers") + return getinteger(i, msg) + a, b = [getbound(i) for i in (a, b)] if rel in subscriptrelations: - return subscriptrelations[rel](repo, subset, x, rel, n, order) + return subscriptrelations[rel](repo, subset, x, rel, a, b, order) relnames = [r for r in subscriptrelations.keys() if len(r) > 1] raise error.UnknownIdentifier(rel, relnames) diff --git a/tests/test-revset.t b/tests/test-revset.t --- a/tests/test-revset.t +++ b/tests/test-revset.t @@ -648,6 +648,9 @@ parse errors of relation, subscript and $ hg debugrevspec '.#generations[1-2]' hg: parse error: relation subscript must be an integer [255] + $ hg debugrevspec '.#generations[foo:bar]' + hg: parse error: relation subscript bounds must be integers + [255] suggested relations @@ -1274,6 +1277,29 @@ test ancestors/descendants relation subs $ log '.#g[(-1)]' 8 + $ log '6#generations[0:2]' + 6 + 7 + $ log '6#generations[-1:2]' + 4 + 5 + 6 + 7 + $ log '6#generations[0:]' + 6 + 7 + $ log '5#generations[:0]' + 0 + 1 + 3 + $ log '3#generations[:]' + 0 + 1 + 3 + 5 + 6 + 7 + $ hg debugrevspec -p parsed 'roots(:)#g[2]' * parsed: (relsubscript