diff mercurial/localrepo.py @ 6321:55ba3bc5b8fd

tag: allow multiple tags to be added or removed - Example: "hg tag -r 42 build-25 beta-1" will add tags build-25 and beta-1 for rev 42. - The deprecated and undocumented usage "hg tag arg1 arg2" used to emit a warning, then add tag arg1 for rev arg2 (equivalent to "hg tag -r arg2 arg1"). It will now add tags arg1 and arg2 for the current revision. - If one tag triggers an error, no tags are added/removed (all or nothing).
author John Coomes <john.coomes@sun.com>
date Fri, 14 Mar 2008 15:38:56 -0700
parents 08800489257e
children 7016f7fb8fe3
line wrap: on
line diff
--- a/mercurial/localrepo.py	Mon Mar 17 19:28:46 2008 +0200
+++ b/mercurial/localrepo.py	Fri Mar 14 15:38:56 2008 -0700
@@ -124,21 +124,29 @@
 
     tag_disallowed = ':\r\n'
 
-    def _tag(self, name, node, message, local, user, date, parent=None,
+    def _tag(self, names, node, message, local, user, date, parent=None,
              extra={}):
         use_dirstate = parent is None
 
+        if isinstance(names, str):
+            allchars = names
+            names = (names,)
+        else:
+            allchars = ''.join(names)
         for c in self.tag_disallowed:
-            if c in name:
+            if c in allchars:
                 raise util.Abort(_('%r cannot be used in a tag name') % c)
 
-        self.hook('pretag', throw=True, node=hex(node), tag=name, local=local)
+        for name in names:
+            self.hook('pretag', throw=True, node=hex(node), tag=name,
+                      local=local)
 
-        def writetag(fp, name, munge, prevtags):
+        def writetags(fp, names, munge, prevtags):
             fp.seek(0, 2)
             if prevtags and prevtags[-1] != '\n':
                 fp.write('\n')
-            fp.write('%s %s\n' % (hex(node), munge and munge(name) or name))
+            for name in names:
+                fp.write('%s %s\n' % (hex(node), munge and munge(name) or name))
             fp.close()
 
         prevtags = ''
@@ -151,8 +159,9 @@
                 prevtags = fp.read()
 
             # local tags are stored in the current charset
-            writetag(fp, name, None, prevtags)
-            self.hook('tag', node=hex(node), tag=name, local=local)
+            writetags(fp, names, None, prevtags)
+            for name in names:
+                self.hook('tag', node=hex(node), tag=name, local=local)
             return
 
         if use_dirstate:
@@ -172,7 +181,7 @@
                 fp.write(prevtags)
 
         # committed tags are stored in UTF-8
-        writetag(fp, name, util.fromlocal, prevtags)
+        writetags(fp, names, util.fromlocal, prevtags)
 
         if use_dirstate and '.hgtags' not in self.dirstate:
             self.add(['.hgtags'])
@@ -180,20 +189,24 @@
         tagnode = self.commit(['.hgtags'], message, user, date, p1=parent,
                               extra=extra)
 
-        self.hook('tag', node=hex(node), tag=name, local=local)
+        for name in names:
+            self.hook('tag', node=hex(node), tag=name, local=local)
 
         return tagnode
 
-    def tag(self, name, node, message, local, user, date):
-        '''tag a revision with a symbolic name.
+    def tag(self, names, node, message, local, user, date):
+        '''tag a revision with one or more symbolic names.
 
-        if local is True, the tag is stored in a per-repository file.
-        otherwise, it is stored in the .hgtags file, and a new
+        names is a list of strings or, when adding a single tag, names may be a
+        string.
+        
+        if local is True, the tags are stored in a per-repository file.
+        otherwise, they are stored in the .hgtags file, and a new
         changeset is committed with the change.
 
         keyword arguments:
 
-        local: whether to store tag in non-version-controlled file
+        local: whether to store tags in non-version-controlled file
         (default False)
 
         message: commit message to use if committing
@@ -207,7 +220,7 @@
                 raise util.Abort(_('working copy of .hgtags is changed '
                                    '(please commit .hgtags manually)'))
 
-        self._tag(name, node, message, local, user, date)
+        self._tag(names, node, message, local, user, date)
 
     def tags(self):
         '''return a mapping of tag to node'''