Show More
@@ -2428,8 +2428,15 b' def tag(ui, repo, name, rev_=None, **opt' | |||||
2428 | rev_ = opts['rev'] |
|
2428 | rev_ = opts['rev'] | |
2429 | message = opts['message'] |
|
2429 | message = opts['message'] | |
2430 | if opts['remove']: |
|
2430 | if opts['remove']: | |
2431 |
|
|
2431 | tagtype = repo.tagtype(name) | |
|
2432 | ||||
|
2433 | if not tagtype: | |||
2432 | raise util.Abort(_('tag %s does not exist') % name) |
|
2434 | raise util.Abort(_('tag %s does not exist') % name) | |
|
2435 | if opts['local'] and tagtype == 'global': | |||
|
2436 | raise util.Abort(_('%s tag is global') % name) | |||
|
2437 | if not opts['local'] and tagtype == 'local': | |||
|
2438 | raise util.Abort(_('%s tag is local') % name) | |||
|
2439 | ||||
2433 | rev_ = nullid |
|
2440 | rev_ = nullid | |
2434 | if not message: |
|
2441 | if not message: | |
2435 | message = _('Removed tag %s') % name |
|
2442 | message = _('Removed tag %s') % name |
@@ -79,6 +79,7 b' class localrepository(repo.repository):' | |||||
79 | pass |
|
79 | pass | |
80 |
|
80 | |||
81 | self.tagscache = None |
|
81 | self.tagscache = None | |
|
82 | self._tagstypecache = None | |||
82 | self.branchcache = None |
|
83 | self.branchcache = None | |
83 | self.nodetagscache = None |
|
84 | self.nodetagscache = None | |
84 | self.filterpats = {} |
|
85 | self.filterpats = {} | |
@@ -198,8 +199,9 b' class localrepository(repo.repository):' | |||||
198 | return self.tagscache |
|
199 | return self.tagscache | |
199 |
|
200 | |||
200 | globaltags = {} |
|
201 | globaltags = {} | |
|
202 | tagtypes = {} | |||
201 |
|
203 | |||
202 | def readtags(lines, fn): |
|
204 | def readtags(lines, fn, tagtype): | |
203 | filetags = {} |
|
205 | filetags = {} | |
204 | count = 0 |
|
206 | count = 0 | |
205 |
|
207 | |||
@@ -234,7 +236,9 b' class localrepository(repo.repository):' | |||||
234 | for k, nh in filetags.items(): |
|
236 | for k, nh in filetags.items(): | |
235 | if k not in globaltags: |
|
237 | if k not in globaltags: | |
236 | globaltags[k] = nh |
|
238 | globaltags[k] = nh | |
|
239 | tagtypes[k] = tagtype | |||
237 | continue |
|
240 | continue | |
|
241 | ||||
238 | # we prefer the global tag if: |
|
242 | # we prefer the global tag if: | |
239 | # it supercedes us OR |
|
243 | # it supercedes us OR | |
240 | # mutual supercedes and it has a higher rank |
|
244 | # mutual supercedes and it has a higher rank | |
@@ -246,31 +250,47 b' class localrepository(repo.repository):' | |||||
246 | an = bn |
|
250 | an = bn | |
247 | ah.extend([n for n in bh if n not in ah]) |
|
251 | ah.extend([n for n in bh if n not in ah]) | |
248 | globaltags[k] = an, ah |
|
252 | globaltags[k] = an, ah | |
|
253 | tagtypes[k] = tagtype | |||
249 |
|
254 | |||
250 | # read the tags file from each head, ending with the tip |
|
255 | # read the tags file from each head, ending with the tip | |
251 | f = None |
|
256 | f = None | |
252 | for rev, node, fnode in self._hgtagsnodes(): |
|
257 | for rev, node, fnode in self._hgtagsnodes(): | |
253 | f = (f and f.filectx(fnode) or |
|
258 | f = (f and f.filectx(fnode) or | |
254 | self.filectx('.hgtags', fileid=fnode)) |
|
259 | self.filectx('.hgtags', fileid=fnode)) | |
255 | readtags(f.data().splitlines(), f) |
|
260 | readtags(f.data().splitlines(), f, "global") | |
256 |
|
261 | |||
257 | try: |
|
262 | try: | |
258 | data = util.fromlocal(self.opener("localtags").read()) |
|
263 | data = util.fromlocal(self.opener("localtags").read()) | |
259 | # localtags are stored in the local character set |
|
264 | # localtags are stored in the local character set | |
260 | # while the internal tag table is stored in UTF-8 |
|
265 | # while the internal tag table is stored in UTF-8 | |
261 | readtags(data.splitlines(), "localtags") |
|
266 | readtags(data.splitlines(), "localtags", "local") | |
262 | except IOError: |
|
267 | except IOError: | |
263 | pass |
|
268 | pass | |
264 |
|
269 | |||
265 | self.tagscache = {} |
|
270 | self.tagscache = {} | |
|
271 | self._tagstypecache = {} | |||
266 | for k,nh in globaltags.items(): |
|
272 | for k,nh in globaltags.items(): | |
267 | n = nh[0] |
|
273 | n = nh[0] | |
268 | if n != nullid: |
|
274 | if n != nullid: | |
269 | self.tagscache[k] = n |
|
275 | self.tagscache[k] = n | |
|
276 | self._tagstypecache[k] = tagtypes[k] | |||
270 | self.tagscache['tip'] = self.changelog.tip() |
|
277 | self.tagscache['tip'] = self.changelog.tip() | |
271 |
|
278 | |||
272 | return self.tagscache |
|
279 | return self.tagscache | |
273 |
|
280 | |||
|
281 | def tagtype(self, tagname): | |||
|
282 | ''' | |||
|
283 | return the type of the given tag. result can be: | |||
|
284 | ||||
|
285 | 'local' : a local tag | |||
|
286 | 'global' : a global tag | |||
|
287 | None : tag does not exist | |||
|
288 | ''' | |||
|
289 | ||||
|
290 | self.tags() | |||
|
291 | ||||
|
292 | return self._tagstypecache.get(tagname) | |||
|
293 | ||||
274 | def _hgtagsnodes(self): |
|
294 | def _hgtagsnodes(self): | |
275 | heads = self.heads() |
|
295 | heads = self.heads() | |
276 | heads.reverse() |
|
296 | heads.reverse() | |
@@ -553,6 +573,7 b' class localrepository(repo.repository):' | |||||
553 | if hasattr(self, a): |
|
573 | if hasattr(self, a): | |
554 | self.__delattr__(a) |
|
574 | self.__delattr__(a) | |
555 | self.tagscache = None |
|
575 | self.tagscache = None | |
|
576 | self._tagstypecache = None | |||
556 | self.nodetagscache = None |
|
577 | self.nodetagscache = None | |
557 |
|
578 | |||
558 | def _lock(self, lockname, wait, releasefn, acquirefn, desc): |
|
579 | def _lock(self, lockname, wait, releasefn, acquirefn, desc): |
@@ -126,3 +126,20 b' hg up -qC 0' | |||||
126 | hg tag -m 'retag rev 0' -fr 0 bar # rev 4 bar -> 0, but bar stays at 2 |
|
126 | hg tag -m 'retag rev 0' -fr 0 bar # rev 4 bar -> 0, but bar stays at 2 | |
127 | echo % bar should still point to rev 2 |
|
127 | echo % bar should still point to rev 2 | |
128 | hg tags |
|
128 | hg tags | |
|
129 | ||||
|
130 | ||||
|
131 | # test that removing global/local tags does not get confused when trying | |||
|
132 | # to remove a tag of type X which actually only exists as a type Y | |||
|
133 | cd .. | |||
|
134 | hg init t5 | |||
|
135 | cd t5 | |||
|
136 | echo foo > foo | |||
|
137 | hg add | |||
|
138 | hg ci -m 'add foo' # rev 0 | |||
|
139 | ||||
|
140 | hg tag -r 0 -l localtag | |||
|
141 | hg tag --remove localtag | |||
|
142 | ||||
|
143 | hg tag -r 0 globaltag | |||
|
144 | hg tag --remove -l globaltag | |||
|
145 | exit 0 |
General Comments 0
You need to be logged in to leave comments.
Login now