changeset 16820:20f55613fb2a

revset: add pattern matching to 'tag' revset expression If the string provided to the 'tag' predicate starts with 're:', the rest of the string will be treated as a regular expression and matched against all tags in the repository. There is a slight backwards-compatibility problem for people who actually have tags that start with 're:'. As a workaround, these tags can be matched using a 'literal:' prefix. If no tags match the pattern, an error is raised. This matches the behaviour of the previous exact-match code.
author Simon King <simon@simonking.org.uk>
date Wed, 30 May 2012 23:13:33 +0100
parents 5260a9e93113
children 0946502fd3d5
files mercurial/revset.py tests/test-revset.t
diffstat 2 files changed, 28 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/revset.py	Wed May 30 23:13:33 2012 +0100
+++ b/mercurial/revset.py	Wed May 30 23:13:33 2012 +0100
@@ -1167,12 +1167,18 @@
     args = getargs(x, 0, 1, _("tag takes one or no arguments"))
     cl = repo.changelog
     if args:
-        tn = getstring(args[0],
-                       # i18n: "tag" is a keyword
-                       _('the argument to tag must be a string'))
-        if not repo.tags().get(tn, None):
-            raise util.Abort(_("tag '%s' does not exist") % tn)
-        s = set([cl.rev(n) for t, n in repo.tagslist() if t == tn])
+        pattern = getstring(args[0],
+                            # i18n: "tag" is a keyword
+                            _('the argument to tag must be a string'))
+        kind, pattern, matcher = _stringmatcher(pattern)
+        if kind == 'literal':
+            if not repo.tags().get(pattern, None):
+                raise util.Abort(_("tag '%s' does not exist") % pattern)
+            s = set([cl.rev(n) for t, n in repo.tagslist() if t == pattern])
+        else:
+            s = set([cl.rev(n) for t, n in repo.tagslist() if matcher(t)])
+            if not s:
+                raise util.Abort(_("no tags exist that match '%s'") % pattern)
     else:
         s = set([cl.rev(n) for t, n in repo.tagslist() if t != 'tip'])
     return [r for r in subset if r in s]
--- a/tests/test-revset.t	Wed May 30 23:13:33 2012 +0100
+++ b/tests/test-revset.t	Wed May 30 23:13:33 2012 +0100
@@ -369,6 +369,22 @@
   6
   $ log 'tag(tip)'
   9
+
+we can use patterns when searching for tags
+
+  $ log 'tag("1..*")'
+  abort: tag '1..*' does not exist
+  [255]
+  $ log 'tag("re:1..*")'
+  6
+  $ log 'tag("re:[0-9].[0-9]")'
+  6
+  $ log 'tag("literal:1.0")'
+  6
+  $ log 'tag("re:0..*")'
+  abort: no tags exist that match '0..*'
+  [255]
+
   $ log 'tag(unknown)'
   abort: tag 'unknown' does not exist
   [255]