--- a/hgext3rd/topic/revset.py Tue Aug 28 11:24:50 2018 +0200
+++ b/hgext3rd/topic/revset.py Mon Sep 03 22:05:12 2018 +0200
@@ -1,13 +1,13 @@
from __future__ import absolute_import
from mercurial import (
+ error,
registrar,
revset,
util,
)
from . import (
- constants,
destination,
stack,
)
@@ -23,36 +23,64 @@
revsetpredicate = registrar.revsetpredicate()
-@revsetpredicate('topic([topic])')
-def topicset(repo, subset, x):
- """Specified topic or all changes with any topic specified.
+def getstringstrict(x, err):
+ if x and (x[0] == 'string'):
+ return x[1]
+ raise error.ParseError(err)
- If `topic` starts with `re:` the remainder of the name is treated
+@revsetpredicate('topic([string or set])')
+def topicset(repo, subset, x):
+ """All changesets with the specified topic or the topics of the given
+ changesets. Without the argument, all changesets with any topic specified.
+
+ 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)`.
"""
args = revset.getargs(x, 0, 1, 'topic takes one or no arguments')
- if args:
- # match a specific topic
- topic = revset.getstring(args[0], 'topic() argument must be a string')
- if topic == '.':
- topic = repo['.'].extra().get('topic', '')
- _kind, _pattern, matcher = mkmatcher(topic)
- else:
- matcher = lambda t: bool(t)
mutable = revset._notpublic(repo, revset.fullreposet(repo), ())
- rawchange = repo.changelog.changelogrevision
- key = constants.extrakey
+ if not args:
+ return (subset & mutable).filter(lambda r: bool(repo[r].topic()))
+
+ try:
+ topic = getstringstrict(args[0], '')
+ except error.ParseError:
+ # not a string, but another revset
+ pass
+ else:
+ kind, pattern, matcher = mkmatcher(topic)
+
+ def matches(r):
+ topic = repo[r].topic()
+ if not topic:
+ return False
+ return matcher(topic)
+
+ if kind == 'literal':
+ # note: falls through to the revset case if no topic with this name
+ # exists and pattern kind is not specified explicitly
- def matchtopic(r):
- topic = rawchange(r).extra.get(key)
- if topic is None:
+ if pattern not in repo.topics and topic.startswith('literal:'):
+ raise error.RepoLookupError("topic '%s' does not exist"
+ % pattern)
+ return (subset & mutable).filter(matches)
+ else:
+ return (subset & mutable).filter(matches)
+
+ s = revset.getset(repo, revset.fullreposet(repo), x)
+ topics = set(repo[r].topic() for r in s)
+ topics.discard('')
+
+ 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):