[PATCH RFC] revset: lookup descendents for negative arguments to ancestor operator
David Soria Parra
davidsp at fb.com
Sat May 27 17:26:09 UTC 2017
# HG changeset patch
# User David Soria Parra <davidsp at fb.com>
# Date 1495905909 25200
# Sat May 27 10:25:09 2017 -0700
# Node ID 47c710c797624b6d5c84c493a873ea8beb563a74
# Parent b647b923486f38d83b92089eafa9faafaa79785d
revset: lookup descendents for negative arguments to ancestor operator
Negative offsets to the `~` operator now search for descendents. The search is
aborted when a node has more than one child as we do not have a definition for
'nth child'. Optionally we can introduce such a notion and take the nth child
ordered by rev number.
The current revset language does provides a short operator for ancestor lookup
but not for descendents. This gives user a simple revset to move to the previous
changeset, e.g. `hg up '.~1'` but not to the 'next' changeset. With this change
userse can now use `.~-1` as a shortcut to move to the next changeset.
This fits better into allowing users to specify revisions via revsets and
avoiding the need for special `hg next` and `hg prev` operations.
The alternative to negative offsets is adding a new operator. We do not have
many operators in ascii left that do not require bash escaping (',', '_', and
'/' come to mind). If we decide that we should add a more convenient short
operator such as ('/', e.g. './1') we can later add it and allow ascendents
lookup via negative numbers.
diff --git a/mercurial/help/revisions.txt b/mercurial/help/revisions.txt
--- a/mercurial/help/revisions.txt
+++ b/mercurial/help/revisions.txt
@@ -97,6 +97,7 @@
``x~n``
The nth first ancestor of x; ``x~0`` is x; ``x~3`` is ``x^^^``.
+ For n < 0, the nth unambiguous descendent of x.
``x ## y``
Concatenate strings and identifiers into one string.
diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -378,12 +378,33 @@
# Like ``ancestors(set)`` but follows only the first parents.
return _ancestors(repo, subset, x, followfirst=True)
+def _childrenspec(repo, subset, x, n, order):
+ """Changesets that are the Nth child of a changeset
+ in set.
+ """
+ cs = set()
+ for r in getset(repo, fullreposet(repo), x):
+ for i in range(n):
+ c = repo[r].children()
+ if len(c) == 0:
+ break
+ if len(c) > 1:
+ raise error.RepoLookupError(
+ _("revision in set has more than one child"))
+ r = c[0]
+ else:
+ cs.add(r)
+ return subset & cs
+
def ancestorspec(repo, subset, x, n, order):
"""``set~n``
Changesets that are the Nth ancestor (first parents only) of a changeset
in set.
"""
n = getinteger(n, _("~ expects a number"))
+ if n < 0:
+ # children lookup
+ return _childrenspec(repo, subset, x, -n, order)
ps = set()
cl = repo.changelog
for r in getset(repo, fullreposet(repo), x):
diff --git a/tests/test-revset.t b/tests/test-revset.t
--- a/tests/test-revset.t
+++ b/tests/test-revset.t
@@ -2881,6 +2881,14 @@
$ log 'merge()^^^'
1
+ $ log '(merge() | 0)~-1'
+ 7
+ 1
+ $ log 'merge()~-1'
+ 7
+ $ log 'tip~-1'
+ $ log '(tip | merge())~-1'
+ 7
$ log 'merge()~0'
6
$ log 'merge()~1'
@@ -2901,6 +2909,10 @@
hg: parse error: ^ expects a number 0, 1, or 2
[255]
+ $ log 'branchpoint()~-1'
+ abort: revset has more than one child!
+ [255]
+
Bogus function gets suggestions
$ log 'add()'
hg: parse error: unknown identifier: add
More information about the Mercurial-devel
mailing list