[PATCH 4 of 4] revset: introduce a 'foo#stack[n]' subscript relation to access stack revisions

Anton Shestakov av6 at dwimlabs.net
Sun Sep 22 23:39:52 EDT 2019


# HG changeset patch
# User Anton Shestakov <av6 at dwimlabs.net>
# Date 1569139969 -25200
#      Sun Sep 22 15:12:49 2019 +0700
# Node ID ab8f097abacb8ce0f9cea2bce0924bb2fd3261a2
# Parent  07af98a1e730c1ffa6911c9ab2cdcc06d4ffe52d
# EXP-Topic stack-object
revset: introduce a 'foo#stack[n]' subscript relation to access stack revisions

The idea behind making n = 0 cases special is that stack base should be
accessible, but only when users ask for it explicitly.

diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -284,6 +284,43 @@ def generationsrel(repo, subset, x, rel,
 
     return subset & s
 
+def stackrel(repo, subset, x, rel, z, order):
+    a, b = getintrange(z,
+                       _('relation subscript must be an integer or a range'),
+                       _('relation subscript bounds must be integers'),
+                       deffirst=None,
+                       deflast=None)
+
+    s = getset(repo, fullreposet(repo), x)
+    if not s:
+        return baseset()
+
+    def getrange(st, a, b):
+        start = 1 if a is None else a
+        end = len(st.indexedrevs) if b is None else b + 1
+        return range(start, end)
+
+    revs = []
+    for r in s:
+        st = stackmod.stack(repo, rev=r)
+        for n in getrange(st, a, b):
+            if abs(n) >= len(st.indexedrevs):
+                # also means stack base is not accessible with n < 0, which
+                # is by design
+                continue
+            if n == 0 and b != 0 and a != 0:
+                # quirk: we don't want stack base unless specifically asked
+                # for it (at least one of the indices is 0)
+                continue
+            rev = st.indexedrevs[n]
+            if rev == node.nullrev and n == 0:
+                # we also don't want stack base if it's nullrev
+                continue
+            if rev not in revs:
+                revs.append(rev)
+
+    return subset & baseset(revs)
+
 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.
@@ -2345,6 +2382,8 @@ methods = {
 subscriptrelations = {
     "g": generationsrel,
     "generations": generationsrel,
+    "s": stackrel,
+    "stack": stackrel,
 }
 
 def lookupfn(repo):
diff --git a/tests/test-stack.t b/tests/test-stack.t
--- a/tests/test-stack.t
+++ b/tests/test-stack.t
@@ -69,7 +69,7 @@ Check that stack doesn't include public 
 Simple test
 -----------
 
-'stack()' list all changeset in the branch
+'stack()' revset lists all changeset in the branch
 
   $ hg branch
   foo
@@ -84,6 +84,48 @@ Simple test
   |
   ~
 
+'#stack[]' (as well as '#s[]') revset relation works
+
+  $ hg log -r 'foo#stack[0]'
+  1 other public c_b
+  $ hg log -r 'foo#stack[1]'
+  2 foo draft c_c
+  $ hg log -r 'foo#stack[2]'
+  3 foo draft c_d
+  $ hg log -r 'foo#stack[-1]'
+  5 foo draft c_f
+  $ hg log -r 'foo#stack[-2]'
+  4 foo draft c_e
+
+  $ hg log -r 'foo#s[0:0]'
+  1 other public c_b
+  $ hg log -r 'foo#s[:]'
+  2 foo draft c_c
+  3 foo draft c_d
+  4 foo draft c_e
+  5 foo draft c_f
+  $ hg log -r 'foo#s[:3]'
+  2 foo draft c_c
+  3 foo draft c_d
+  4 foo draft c_e
+  $ hg log -r 'foo#s[3:]'
+  4 foo draft c_e
+  5 foo draft c_f
+  $ hg log -r 'foo#s[0:1]'
+  1 other public c_b
+  2 foo draft c_c
+  $ hg log -r 'foo#s[-1:0]'
+  1 other public c_b
+  5 foo draft c_f
+  $ hg log -r 'foo#s[-4:4]'
+  2 foo draft c_c
+  3 foo draft c_d
+  4 foo draft c_e
+  5 foo draft c_f
+
+  $ hg log -r 'all()#s[9999]'
+  $ hg log -r 'all()#s[-9999]'
+
 Case with some of the branch unstable
 ------------------------------------
 


More information about the Mercurial-devel mailing list