diff --git a/hgext/remotenames.py b/hgext/remotenames.py --- a/hgext/remotenames.py +++ b/hgext/remotenames.py @@ -42,6 +42,10 @@ templateutil, ) +from mercurial.utils import ( + stringutil, +) + if pycompat.ispy3: import collections.abc mutablemapping = collections.abc.MutableMapping @@ -347,13 +351,22 @@ revs = set() cl = repo.changelog + literals, matchers = paths + # whether arguments were passed or not + argspassed = bool(literals or matchers) for rtype in rtypes: if rtype in repo.names: ns = repo.names[rtype] for name in ns.listnames(repo): - if paths: - if name.split('/')[0] in paths: + if argspassed: + rname = name.split('/')[0] + if rname in literals: revs.update(ns.nodes(repo, name)) + continue + for matcher in matchers: + if matcher(rname): + revs.update(ns.nodes(repo, name)) + break else: revs.update(ns.nodes(repo, name)) @@ -361,23 +374,41 @@ return subset & smartset.baseset(sorted(results)) def _parsepaths(x): - """parses the argument passed in revsets as paths and return - them as a set or returns None if no path is specified""" + """parses the argument passed in revsets as paths + + returns (literals, matchers) where, + literals is a set of literals passed by user + matchers is a list of matcher objects for patterns passed by user + """ + + # set of paths passed as literals + literals = set() + # list of matcher to match the patterns passed as paths + matchers = [] if not x: - return None + return literals, matchers paths = set() lx = revsetlang.getlist(x) err = _('the argument must be a string') for entry in lx: paths.add(revsetlang.getstring(entry, err)) - return paths + for p in paths: + kind, pattern, matcher = stringutil.stringmatcher(p) + if kind == 'literal': + literals.add(pattern) + else: + matchers.append(matcher) + return literals, matchers @revsetpredicate('remotenames([path, ...])') def remotenamesrevset(repo, subset, x): """All changesets which have a remotename on them. If paths are specified, - remotenames of those remote paths are only considered.""" + remotenames of those remote paths are only considered. + + Pattern matching is supported for `path`. See :hg:`help revisions.patterns`. + """ paths = _parsepaths(x) return _revsetutil(repo, subset, x, ('remotebookmarks', 'remotebranches'), @@ -386,7 +417,10 @@ @revsetpredicate('remotebranches([path, ...])') def remotebranchesrevset(repo, subset, x): """All changesets which are branch heads on remotes. If paths are specified, - only those remotes paths are considered""" + only those remotes paths are considered. + + Pattern matching is supported for `path`. See :hg:`help revisions.patterns`. + """ paths = _parsepaths(x) return _revsetutil(repo, subset, x, ('remotebranches',), paths) @@ -394,7 +428,10 @@ @revsetpredicate('remotebookmarks([path, ...])') def remotebmarksrevset(repo, subset, x): """All changesets which have bookmarks on remotes. If paths are specified, - only those remote paths are considered""" + only those remote paths are considered. + + Pattern matching is supported for `path`. See :hg:`help revisions.patterns`. + """ paths = _parsepaths(x) return _revsetutil(repo, subset, x, ('remotebookmarks',), paths) diff --git a/tests/test-logexchange.t b/tests/test-logexchange.t --- a/tests/test-logexchange.t +++ b/tests/test-logexchange.t @@ -566,3 +566,31 @@ $ hg log -r 'remotebookmarks(delt, serv)' -GT "{rev}:{node|short} {remotebookmarks}\n" +Testing pattern matching + + $ hg log -r 'remotenames("re:def")' -GT "{rev}:{node|short} {remotenames}\n" + o 8:3e1487808078 default/foo default/wat + | + ~ + @ 7:ec2426147f0e default/default + | + o 6:87d6d6676308 default/bar server2/bar + | + ~ + + $ hg log -r 'remotebranches("re:ser.*2")' -GT "{rev}:{node|short} {remotebranches}\n" + o 10:bf433e48adea server2/default + | + ~ + o 9:f34adec73c21 server2/wat + | + ~ + + $ hg log -r 'remotebookmarks("re:def", "re:.*2")' -GT "{rev}:{node|short} {remotebookmarks}\n" + o 8:3e1487808078 default/foo + : + : o 6:87d6d6676308 default/bar server2/bar + :/ + o 3:62615734edd5 server2/foo + | + ~