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.
--- 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
======================================================