95 self.opener.createmode = self.store.createmode |
95 self.opener.createmode = self.store.createmode |
96 self._applyrequirements(requirements) |
96 self._applyrequirements(requirements) |
97 if create: |
97 if create: |
98 self._writerequirements() |
98 self._writerequirements() |
99 |
99 |
100 # These two define the set of tags for this repository. _tags |
|
101 # maps tag name to node; _tagtypes maps tag name to 'global' or |
|
102 # 'local'. (Global tags are defined by .hgtags across all |
|
103 # heads, and local tags are defined in .hg/localtags.) They |
|
104 # constitute the in-memory cache of tags. |
|
105 self._tags = None |
|
106 self._tagtypes = None |
|
107 |
100 |
108 self._branchcache = None |
101 self._branchcache = None |
109 self._branchcachetip = None |
102 self._branchcachetip = None |
110 self.nodetagscache = None |
|
111 self.filterpats = {} |
103 self.filterpats = {} |
112 self._datafilters = {} |
104 self._datafilters = {} |
113 self._transref = self._lockref = self._wlockref = None |
105 self._transref = self._lockref = self._wlockref = None |
114 |
106 |
115 # A cache for various files under .hg/ that tracks file changes, |
107 # A cache for various files under .hg/ that tracks file changes, |
266 fp.seek(0, 2) |
258 fp.seek(0, 2) |
267 if prevtags and prevtags[-1] != '\n': |
259 if prevtags and prevtags[-1] != '\n': |
268 fp.write('\n') |
260 fp.write('\n') |
269 for name in names: |
261 for name in names: |
270 m = munge and munge(name) or name |
262 m = munge and munge(name) or name |
271 if self._tagtypes and name in self._tagtypes: |
263 if self._tagscache.tagtypes and name in self._tagscache.tagtypes: |
272 old = self._tags.get(name, nullid) |
264 old = self.tags().get(name, nullid) |
273 fp.write('%s %s\n' % (hex(old), m)) |
265 fp.write('%s %s\n' % (hex(old), m)) |
274 fp.write('%s %s\n' % (hex(node), m)) |
266 fp.write('%s %s\n' % (hex(node), m)) |
275 fp.close() |
267 fp.close() |
276 |
268 |
277 prevtags = '' |
269 prevtags = '' |
342 '(please commit .hgtags manually)')) |
334 '(please commit .hgtags manually)')) |
343 |
335 |
344 self.tags() # instantiate the cache |
336 self.tags() # instantiate the cache |
345 self._tag(names, node, message, local, user, date) |
337 self._tag(names, node, message, local, user, date) |
346 |
338 |
|
339 @propertycache |
|
340 def _tagscache(self): |
|
341 '''Returns a tagscache object that contains various tags related caches.''' |
|
342 |
|
343 # This simplifies its cache management by having one decorated |
|
344 # function (this one) and the rest simply fetch things from it. |
|
345 class tagscache(object): |
|
346 def __init__(self): |
|
347 # These two define the set of tags for this repository. tags |
|
348 # maps tag name to node; tagtypes maps tag name to 'global' or |
|
349 # 'local'. (Global tags are defined by .hgtags across all |
|
350 # heads, and local tags are defined in .hg/localtags.) |
|
351 # They constitute the in-memory cache of tags. |
|
352 self.tags = self.tagtypes = None |
|
353 |
|
354 self.nodetagscache = self.tagslist = None |
|
355 |
|
356 cache = tagscache() |
|
357 cache.tags, cache.tagtypes = self._findtags() |
|
358 |
|
359 return cache |
|
360 |
347 def tags(self): |
361 def tags(self): |
348 '''return a mapping of tag to node''' |
362 '''return a mapping of tag to node''' |
349 if self._tags is None: |
363 return self._tagscache.tags |
350 (self._tags, self._tagtypes) = self._findtags() |
|
351 |
|
352 return self._tags |
|
353 |
364 |
354 def _findtags(self): |
365 def _findtags(self): |
355 '''Do the hard work of finding tags. Return a pair of dicts |
366 '''Do the hard work of finding tags. Return a pair of dicts |
356 (tags, tagtypes) where tags maps tag name to node, and tagtypes |
367 (tags, tagtypes) where tags maps tag name to node, and tagtypes |
357 maps tag name to a string like \'global\' or \'local\'. |
368 maps tag name to a string like \'global\' or \'local\'. |
396 'local' : a local tag |
407 'local' : a local tag |
397 'global' : a global tag |
408 'global' : a global tag |
398 None : tag does not exist |
409 None : tag does not exist |
399 ''' |
410 ''' |
400 |
411 |
401 self.tags() |
412 return self._tagscache.tagtypes.get(tagname) |
402 |
|
403 return self._tagtypes.get(tagname) |
|
404 |
413 |
405 def tagslist(self): |
414 def tagslist(self): |
406 '''return a list of tags ordered by revision''' |
415 '''return a list of tags ordered by revision''' |
407 l = [] |
416 if not self._tagscache.tagslist: |
408 for t, n in self.tags().iteritems(): |
417 l = [] |
409 r = self.changelog.rev(n) |
418 for t, n in self.tags().iteritems(): |
410 l.append((r, t, n)) |
419 r = self.changelog.rev(n) |
411 return [(t, n) for r, t, n in sorted(l)] |
420 l.append((r, t, n)) |
|
421 self._tagscache.tagslist = [(t, n) for r, t, n in sorted(l)] |
|
422 |
|
423 return self._tagscache.tagslist |
412 |
424 |
413 def nodetags(self, node): |
425 def nodetags(self, node): |
414 '''return the tags associated with a node''' |
426 '''return the tags associated with a node''' |
415 if not self.nodetagscache: |
427 if not self._tagscache.nodetagscache: |
416 self.nodetagscache = {} |
428 nodetagscache = {} |
417 for t, n in self.tags().iteritems(): |
429 for t, n in self.tags().iteritems(): |
418 self.nodetagscache.setdefault(n, []).append(t) |
430 nodetagscache.setdefault(n, []).append(t) |
419 for tags in self.nodetagscache.itervalues(): |
431 for tags in nodetagscache.itervalues(): |
420 tags.sort() |
432 tags.sort() |
421 return self.nodetagscache.get(node, []) |
433 self._tagscache.nodetagscache = nodetagscache |
|
434 return self._tagscache.nodetagscache.get(node, []) |
422 |
435 |
423 def nodebookmarks(self, node): |
436 def nodebookmarks(self, node): |
424 marks = [] |
437 marks = [] |
425 for bookmark, n in self._bookmarks.iteritems(): |
438 for bookmark, n in self._bookmarks.iteritems(): |
426 if n == node: |
439 if n == node: |
790 return 1 |
803 return 1 |
791 finally: |
804 finally: |
792 release(lock, wlock) |
805 release(lock, wlock) |
793 |
806 |
794 def invalidatecaches(self): |
807 def invalidatecaches(self): |
795 self._tags = None |
808 try: |
796 self._tagtypes = None |
809 delattr(self, '_tagscache') |
797 self.nodetagscache = None |
810 except AttributeError: |
|
811 pass |
|
812 |
798 self._branchcache = None # in UTF-8 |
813 self._branchcache = None # in UTF-8 |
799 self._branchcachetip = None |
814 self._branchcachetip = None |
800 |
815 |
801 def invalidatedirstate(self): |
816 def invalidatedirstate(self): |
802 '''Invalidates the dirstate, causing the next call to dirstate |
817 '''Invalidates the dirstate, causing the next call to dirstate |