changeset 4322:41f38bf15b4c

topic: make revsets like 'foo#stack[0]' work 'stack' relation subscript function is another way to refer to s0, s1, etc. But instead of aborting in many cases it will simply return an empty set.
author Anton Shestakov <av6@dwimlabs.net>
date Sun, 16 Dec 2018 11:22:04 +0800
parents 00d1963f50e5
children 482992803db6
files hgext3rd/topic/revset.py tests/test-topic-stack.t tests/test-topic.t
diffstat 3 files changed, 125 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/hgext3rd/topic/revset.py	Sat Dec 22 01:29:59 2018 -0500
+++ b/hgext3rd/topic/revset.py	Sun Dec 16 11:22:04 2018 +0800
@@ -106,3 +106,37 @@
     else:
         branch = repo[None].branch()
     return revset.baseset(stack.stack(repo, branch=branch, topic=topic)[1:]) & subset
+
+if util.safehasattr(revset, 'subscriptrelations'):
+    def stackrel(repo, subset, x, rel, n, order):
+        """This is a revset-flavored implementation of stack aliases.
+
+        The syntax is: rev#stack[n] or rev#s[n]. Plenty of logic is borrowed
+        from topic._namemap, but unlike that function, which prefers to abort
+        (e.g. when stack index is too high), this returns empty set to be more
+        revset-friendly.
+        """
+        if n < 0:
+            return revset.baseset()
+        s = revset.getset(repo, revset.fullreposet(repo), x)
+        if not s:
+            return revset.baseset()
+        revs = []
+        for r in s:
+            topic = repo[r].topic()
+            if topic:
+                st = stack.stack(repo, topic=topic)
+            else:
+                st = stack.stack(repo, branch=repo[r].branch())
+            try:
+                rev = list(st)[n]
+            except IndexError:
+                continue
+            if rev == -1 and n == 0:
+                continue
+            if rev not in revs:
+                revs.append(rev)
+        return subset & revset.baseset(revs)
+
+    revset.subscriptrelations['stack'] = stackrel
+    revset.subscriptrelations['s'] = stackrel
--- a/tests/test-topic-stack.t	Sat Dec 22 01:29:59 2018 -0500
+++ b/tests/test-topic-stack.t	Sun Dec 16 11:22:04 2018 +0800
@@ -373,6 +373,17 @@
   hg: parse error: stack takes no arguments, it works on current topic
   [255]
 
+Stack relation subscript:
+
+  $ hg log -r 'foo#stack[0]'
+  1 default {} public c_b
+  $ hg log -r 's0 and foo#stack[0]'
+  1 default {} public c_b
+  $ hg log -r 'foo#stack[4]'
+  5 default {foo} draft c_f
+  $ hg log -r 's4 and foo#stack[4]'
+  5 default {foo} draft c_f
+
 Case with multiple heads on the topic
 -------------------------------------
 
--- a/tests/test-topic.t	Sat Dec 22 01:29:59 2018 -0500
+++ b/tests/test-topic.t	Sun Dec 16 11:22:04 2018 +0800
@@ -823,6 +823,86 @@
 
   $ cd ..
 
+Stack relation subscript in revsets
+===================================
+
+  $ hg init more-than-one-commit-per-topic
+  $ cd more-than-one-commit-per-topic
+  $ cat > .hg/hgrc << EOF
+  > [phases]
+  > publish=false
+  > EOF
+
+  $ echo 0 > foo
+  $ hg ci -qAm 0
+  $ hg topic featureA
+  marked working directory as topic: featureA
+  $ echo 1 > foo
+  $ hg ci -qm 1
+  $ echo 2 > foo
+  $ hg ci -qm 2
+  $ echo 3 > foo
+  $ hg ci -qm 3
+  $ hg topic --clear
+  $ echo 4 > foo
+  $ hg ci -qm 4
+
+  $ tlog 'all()'
+  0: 
+  1: featureA
+  2: featureA
+  3: featureA
+  4: 
+
+  $ hg stack
+  ### target: default (branch)
+  s2@ 4 (current)
+    ^ 3
+  s1: 0
+
+  $ tlog 'tip#stack[0]'
+  $ tlog 'tip#stack[1]'
+  0: 
+  $ tlog 'tip#stack[2]'
+  4: 
+
+  $ hg stack featureA
+  ### topic: featureA
+  ### target: default (branch), 3 behind
+  s3: 3
+  s2: 2
+  s1: 1
+  s0^ 0 (base)
+
+  $ tlog 'featureA#s[0]'
+  0: 
+  $ tlog 'featureA#s[1]'
+  1: featureA
+  $ tlog 'featureA#s[2]'
+  2: featureA
+  $ tlog 'featureA#s[3]'
+  3: featureA
+
+  $ tlog 'all()#s[-1]'
+  $ tlog 'all()#s[0]'
+  0: 
+  $ tlog 'all()#s[1]'
+  0: 
+  1: featureA
+  $ tlog 'all()#s[9999]'
+
+  $ hg topic featureB
+  marked working directory as topic: featureB
+  $ hg stack
+  ### topic: featureB
+  ### target: default (branch)
+  (stack is empty)
+  s0^ 4 (base current)
+  $ tlog 'wdir()#s[0]'
+  4: 
+
+  $ cd ..
+
 Testing the new config knob to forbid untopiced commit
 ======================================================