D3844: remotenames: add support to accept literal/re pattern in revsets

pulkit (Pulkit Goyal) phabricator at mercurial-scm.org
Tue Jun 26 21:46:34 UTC 2018


pulkit created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  This patch add supports to remotenames(), remotebookmarks() and remotebranches()
  revsets to accept literal/re patterns which is similar to the behavior what we
  have in bookmark() revset.
  
  New tests are added for pattern matching and not breaking of existing tests
  shows that we are fine.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D3844

AFFECTED FILES
  hgext/remotenames.py
  tests/test-logexchange.t

CHANGE DETAILS

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
+  |
+  ~
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,54 +351,87 @@
 
     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))
 
     results = (cl.rev(n) for n in revs if cl.hasnode(n))
     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'),
                        paths)
 
 @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)
 
 @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)



To: pulkit, #hg-reviewers
Cc: mercurial-devel


More information about the Mercurial-devel mailing list