hgext3rd/topic/revset.py
changeset 4060 54eade86ac31
parent 4059 1914a53fe792
child 4061 ad4194399b47
--- 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):