Properly check tag's existence as a local/global tag when removing it.
authorOsku Salerma <osku@iki.fi>
Sun, 09 Dec 2007 16:32:05 +0900
changeset 5657 47915bf68c44
parent 5656 b940260c4291
child 5658 ae3089cefaab
Properly check tag's existence as a local/global tag when removing it.
mercurial/commands.py
mercurial/localrepo.py
tests/test-tags
tests/test-tags.out
--- a/mercurial/commands.py	Tue Dec 18 14:01:34 2007 -0600
+++ b/mercurial/commands.py	Sun Dec 09 16:32:05 2007 +0900
@@ -2428,8 +2428,15 @@
         rev_ = opts['rev']
     message = opts['message']
     if opts['remove']:
-        if not name in repo.tags():
+        tagtype = repo.tagtype(name)
+
+        if not tagtype:
             raise util.Abort(_('tag %s does not exist') % name)
+        if opts['local'] and tagtype == 'global':
+           raise util.Abort(_('%s tag is global') % name)
+        if not opts['local'] and tagtype == 'local':
+           raise util.Abort(_('%s tag is local') % name)
+
         rev_ = nullid
         if not message:
             message = _('Removed tag %s') % name
--- a/mercurial/localrepo.py	Tue Dec 18 14:01:34 2007 -0600
+++ b/mercurial/localrepo.py	Sun Dec 09 16:32:05 2007 +0900
@@ -79,6 +79,7 @@
             pass
 
         self.tagscache = None
+        self._tagstypecache = None
         self.branchcache = None
         self.nodetagscache = None
         self.filterpats = {}
@@ -198,8 +199,9 @@
             return self.tagscache
 
         globaltags = {}
+        tagtypes = {}
 
-        def readtags(lines, fn):
+        def readtags(lines, fn, tagtype):
             filetags = {}
             count = 0
 
@@ -234,7 +236,9 @@
             for k, nh in filetags.items():
                 if k not in globaltags:
                     globaltags[k] = nh
+                    tagtypes[k] = tagtype
                     continue
+
                 # we prefer the global tag if:
                 #  it supercedes us OR
                 #  mutual supercedes and it has a higher rank
@@ -246,31 +250,47 @@
                     an = bn
                 ah.extend([n for n in bh if n not in ah])
                 globaltags[k] = an, ah
+                tagtypes[k] = tagtype
 
         # read the tags file from each head, ending with the tip
         f = None
         for rev, node, fnode in self._hgtagsnodes():
             f = (f and f.filectx(fnode) or
                  self.filectx('.hgtags', fileid=fnode))
-            readtags(f.data().splitlines(), f)
+            readtags(f.data().splitlines(), f, "global")
 
         try:
             data = util.fromlocal(self.opener("localtags").read())
             # localtags are stored in the local character set
             # while the internal tag table is stored in UTF-8
-            readtags(data.splitlines(), "localtags")
+            readtags(data.splitlines(), "localtags", "local")
         except IOError:
             pass
 
         self.tagscache = {}
+        self._tagstypecache = {}
         for k,nh in globaltags.items():
             n = nh[0]
             if n != nullid:
                 self.tagscache[k] = n
+                self._tagstypecache[k] = tagtypes[k]
         self.tagscache['tip'] = self.changelog.tip()
 
         return self.tagscache
 
+    def tagtype(self, tagname):
+        '''
+        return the type of the given tag. result can be:
+
+        'local'  : a local tag
+        'global' : a global tag
+        None     : tag does not exist
+        '''
+
+        self.tags()
+ 
+        return self._tagstypecache.get(tagname)
+
     def _hgtagsnodes(self):
         heads = self.heads()
         heads.reverse()
@@ -553,6 +573,7 @@
             if hasattr(self, a):
                 self.__delattr__(a)
         self.tagscache = None
+        self._tagstypecache = None
         self.nodetagscache = None
 
     def _lock(self, lockname, wait, releasefn, acquirefn, desc):
--- a/tests/test-tags	Tue Dec 18 14:01:34 2007 -0600
+++ b/tests/test-tags	Sun Dec 09 16:32:05 2007 +0900
@@ -126,3 +126,20 @@
 hg tag -m 'retag rev 0' -fr 0 bar  # rev 4 bar -> 0, but bar stays at 2
 echo % bar should still point to rev 2
 hg tags
+
+
+# test that removing global/local tags does not get confused when trying
+# to remove a tag of type X which actually only exists as a type Y
+cd ..
+hg init t5
+cd t5
+echo foo > foo
+hg add
+hg ci -m 'add foo'                 # rev 0
+
+hg tag -r 0 -l localtag
+hg tag --remove localtag
+
+hg tag -r 0 globaltag
+hg tag --remove -l globaltag
+exit 0
--- a/tests/test-tags.out	Tue Dec 18 14:01:34 2007 -0600
+++ b/tests/test-tags.out	Sun Dec 09 16:32:05 2007 +0900
@@ -71,3 +71,6 @@
 % bar should still point to rev 2
 tip                                4:40af5d225513
 bar                                2:72b852876a42
+adding foo
+abort: localtag tag is local
+abort: globaltag tag is global