topic: handle revsets passed to topic() revset
authorAnton Shestakov <av6@dwimlabs.net>
Thu, 30 Aug 2018 20:21:17 +0800
changeset 4060 54eade86ac31
parent 4059 1914a53fe792
child 4061 ad4194399b47
topic: handle revsets passed to topic() revset This handles cases when the argument can't be interpreted as a string at all.
hgext3rd/topic/revset.py
tests/test-topic.t
--- a/hgext3rd/topic/revset.py	Thu Aug 30 19:13:56 2018 +0800
+++ b/hgext3rd/topic/revset.py	Thu Aug 30 20:21:17 2018 +0800
@@ -8,7 +8,6 @@
 )
 
 from . import (
-    constants,
     destination,
     stack,
 )
@@ -24,11 +23,12 @@
 
 revsetpredicate = registrar.revsetpredicate()
 
-@revsetpredicate('topic([topic])')
+@revsetpredicate('topic([string or set])')
 def topicset(repo, subset, x):
-    """Specified topic or all changes with any topic specified.
+    """All changesets with the specified topic or the topics of the given
+    changesets. Without the argument, all changesets with any topic specified.
 
-    If `topic` starts with `re:` the remainder of the name is treated
+    If `string` starts with `re:` the remainder of the name is treated
     as a regular expression.
 
     TODO: make `topic(revset)` work the same as `branch(revset)`.
@@ -41,10 +41,10 @@
         return (subset & mutable).filter(lambda r: bool(repo[r].topic()))
 
     try:
-        topic = revset.getstring(args[0], 'topic() argument must be a string')
+        topic = revset.getstring(args[0], '')
     except error.ParseError:
         # not a string, but another revset
-        raise
+        pass
     else:
         if topic == '.':
             topic = repo['.'].extra().get('topic', '')
@@ -59,15 +59,19 @@
         if True:
             return (subset & mutable).filter(matches)
 
-    rawchange = repo.changelog.changelogrevision
-    key = constants.extrakey
+    s = revset.getset(repo, revset.fullreposet(repo), x)
+    topics = set(repo[r].topic() for r in s)
+    topics.discard('')
 
-    def matchtopic(r):
-        topic = rawchange(r).extra.get(key)
-        if topic is None:
+    def matches(r):
+        if r in s:
+            return True
+        topic = repo[r].topic()
+        if not topic:
             return False
-        return matcher(topic)
-    return (subset & mutable).filter(matchtopic)
+        return topic in topics
+
+    return (subset & mutable).filter(matches)
 
 @revsetpredicate('ngtip([branch])')
 def ngtipset(repo, subset, x):
--- a/tests/test-topic.t	Thu Aug 30 19:13:56 2018 +0800
+++ b/tests/test-topic.t	Thu Aug 30 20:21:17 2018 +0800
@@ -736,10 +736,27 @@
   summary:     start on fran
   
 
+Using revsets in topic()
+  $ tlog() {
+  >   hg log -T '{rev}: {topic}\n' -r "$1"
+  > }
+
+  $ tlog 'topic(head())'
+  9: fran
+  $ tlog 'topic(:)'
+  9: fran
+  $ tlog 'topic(all())'
+  9: fran
+  $ tlog 'topic(topic(fran))'
+  9: fran
+  $ tlog 'topic(wdir())'
+  9: fran
+
 Deactivate the topic.
   $ hg topics
    * fran (1 changesets)
   $ hg topics --clear
+  $ hg log -r 'topic(wdir())'
   $ echo fran? >> beta
   $ hg ci -m 'fran?'
   created new head