topic: make ranges work in revset relations like 'foo#stack[1:2]'
authorAnton Shestakov <av6@dwimlabs.net>
Tue, 29 Jan 2019 20:45:14 +0800
changeset 4381 5f1d0cff514d
parent 4380 c73edc31e0dd
child 4382 e6ba7e324015
topic: make ranges work in revset relations like 'foo#stack[1:2]'
hgext3rd/topic/revset.py
tests/test-topic.t
--- a/hgext3rd/topic/revset.py	Mon Jan 28 22:31:31 2019 +0800
+++ b/hgext3rd/topic/revset.py	Tue Jan 29 20:45:14 2019 +0800
@@ -108,7 +108,7 @@
     return revset.baseset(stack.stack(repo, branch=branch, topic=topic)[1:]) & subset
 
 if util.safehasattr(revset, 'subscriptrelations'):
-    def stackrel(repo, subset, x, rel, n, *args):
+    def stackrel(repo, subset, x, rel, a, *args):
         """This is a revset-flavored implementation of stack aliases.
 
         The syntax is: rev#stack[n] or rev#s[n]. Plenty of logic is borrowed
@@ -116,12 +116,21 @@
         (e.g. when stack index is too high), this returns empty set to be more
         revset-friendly.
         """
-        # hg 5.0 provides two bounds, for now we support only one
-        if len(args) == 2 and args[0] != n:
-            raise NotImplementedError
+        # hg 4.9 provides one bound, hg 5.0 provides two
+        if len(args) == 2:
+            b = args[0]
+        else:
+            b = a
+
         s = revset.getset(repo, revset.fullreposet(repo), x)
         if not s:
             return revset.baseset()
+
+        def getrange(st, a, b):
+            start = 1 if a is None else a
+            end = len(st.revs) if b is None else b + 1
+            return range(start, end)
+
         revs = []
         for r in s:
             topic = repo[r].topic()
@@ -129,15 +138,21 @@
                 st = stack.stack(repo, topic=topic)
             else:
                 st = stack.stack(repo, branch=repo[r].branch())
-            if abs(n) >= len(st.revs):
-                # also means stack base is not accessible with n < 0, which is
-                # by design
-                continue
-            rev = st.revs[n]
-            if rev == -1 and n == 0:
-                continue
-            if rev not in revs:
-                revs.append(rev)
+            for n in getrange(st, a, b):
+                if abs(n) >= len(st.revs):
+                    # 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.revs[n]
+                if rev == -1 and n == 0:
+                    continue
+                if rev not in revs:
+                    revs.append(rev)
+
         return subset & revset.baseset(revs)
 
     revset.subscriptrelations['stack'] = stackrel
--- a/tests/test-topic.t	Mon Jan 28 22:31:31 2019 +0800
+++ b/tests/test-topic.t	Tue Jan 29 20:45:14 2019 +0800
@@ -906,6 +906,28 @@
 
   $ tlog 'featureA#s[0]'
   0: 
+  $ tlog 'featureA#s[0:0]'
+  0: 
+  $ tlog 'featureA#s[:]'
+  1: featureA
+  2: featureA
+  3: featureA
+  $ tlog 'featureA#s[2:]'
+  2: featureA
+  3: featureA
+  $ tlog 'featureA#s[:2]'
+  1: featureA
+  2: featureA
+  $ tlog 'featureA#s[0:1]'
+  0: 
+  1: featureA
+  $ tlog 'featureA#s[-1:0]'
+  0: 
+  3: featureA
+  $ tlog 'featureA#s[-3:3]'
+  1: featureA
+  2: featureA
+  3: featureA
   $ tlog 'featureA#s[1] and featureA#s[-3]'
   1: featureA
   $ tlog 'featureA#s[2] and featureA#s[-2]'