hgext3rd/topic/revset.py
branchmercurial-4.5
changeset 4075 dc247e648f43
parent 4064 a2c0133006c6
child 4095 aabf436c11cb
equal deleted inserted replaced
4031:9a2db13b2e99 4075:dc247e648f43
     1 from __future__ import absolute_import
     1 from __future__ import absolute_import
     2 
     2 
     3 from mercurial import (
     3 from mercurial import (
       
     4     error,
     4     registrar,
     5     registrar,
     5     revset,
     6     revset,
     6     util,
     7     util,
     7 )
     8 )
     8 
     9 
     9 from . import (
    10 from . import (
    10     constants,
       
    11     destination,
    11     destination,
    12     stack,
    12     stack,
    13 )
    13 )
    14 
    14 
    15 try:
    15 try:
    21     except (ImportError, AttributeError):
    21     except (ImportError, AttributeError):
    22         mkmatcher = util.stringmatcher
    22         mkmatcher = util.stringmatcher
    23 
    23 
    24 revsetpredicate = registrar.revsetpredicate()
    24 revsetpredicate = registrar.revsetpredicate()
    25 
    25 
    26 @revsetpredicate('topic([topic])')
    26 def getstringstrict(x, err):
       
    27     if x and (x[0] == 'string'):
       
    28         return x[1]
       
    29     raise error.ParseError(err)
       
    30 
       
    31 @revsetpredicate('topic([string or set])')
    27 def topicset(repo, subset, x):
    32 def topicset(repo, subset, x):
    28     """Specified topic or all changes with any topic specified.
    33     """All changesets with the specified topic or the topics of the given
       
    34     changesets. Without the argument, all changesets with any topic specified.
    29 
    35 
    30     If `topic` starts with `re:` the remainder of the name is treated
    36     If `string` starts with `re:` the remainder of the name is treated
    31     as a regular expression.
    37     as a regular expression.
    32 
       
    33     TODO: make `topic(revset)` work the same as `branch(revset)`.
       
    34     """
    38     """
    35     args = revset.getargs(x, 0, 1, 'topic takes one or no arguments')
    39     args = revset.getargs(x, 0, 1, 'topic takes one or no arguments')
    36     if args:
       
    37         # match a specific topic
       
    38         topic = revset.getstring(args[0], 'topic() argument must be a string')
       
    39         if topic == '.':
       
    40             topic = repo['.'].extra().get('topic', '')
       
    41         _kind, _pattern, matcher = mkmatcher(topic)
       
    42     else:
       
    43         matcher = lambda t: bool(t)
       
    44 
    40 
    45     mutable = revset._notpublic(repo, revset.fullreposet(repo), ())
    41     mutable = revset._notpublic(repo, revset.fullreposet(repo), ())
    46 
    42 
    47     rawchange = repo.changelog.changelogrevision
    43     if not args:
    48     key = constants.extrakey
    44         return (subset & mutable).filter(lambda r: bool(repo[r].topic()))
    49 
    45 
    50     def matchtopic(r):
    46     try:
    51         topic = rawchange(r).extra.get(key)
    47         topic = getstringstrict(args[0], '')
    52         if topic is None:
    48     except error.ParseError:
       
    49         # not a string, but another revset
       
    50         pass
       
    51     else:
       
    52         kind, pattern, matcher = mkmatcher(topic)
       
    53 
       
    54         def matches(r):
       
    55             topic = repo[r].topic()
       
    56             if not topic:
       
    57                 return False
       
    58             return matcher(topic)
       
    59 
       
    60         if kind == 'literal':
       
    61             # note: falls through to the revset case if no topic with this name
       
    62             # exists and pattern kind is not specified explicitly
       
    63 
       
    64             if pattern not in repo.topics and topic.startswith('literal:'):
       
    65                 raise error.RepoLookupError("topic '%s' does not exist"
       
    66                                             % pattern)
       
    67             return (subset & mutable).filter(matches)
       
    68         else:
       
    69             return (subset & mutable).filter(matches)
       
    70 
       
    71     s = revset.getset(repo, revset.fullreposet(repo), x)
       
    72     topics = set(repo[r].topic() for r in s)
       
    73     topics.discard('')
       
    74 
       
    75     def matches(r):
       
    76         if r in s:
       
    77             return True
       
    78         topic = repo[r].topic()
       
    79         if not topic:
    53             return False
    80             return False
    54         return matcher(topic)
    81         return topic in topics
    55     return (subset & mutable).filter(matchtopic)
    82 
       
    83     return (subset & mutable).filter(matches)
    56 
    84 
    57 @revsetpredicate('ngtip([branch])')
    85 @revsetpredicate('ngtip([branch])')
    58 def ngtipset(repo, subset, x):
    86 def ngtipset(repo, subset, x):
    59     """The untopiced tip.
    87     """The untopiced tip.
    60 
    88