mercurial/tags.py
changeset 43076 2372284d9457
parent 42567 4eaf7197a740
child 43077 687b865b95ad
--- a/mercurial/tags.py	Sat Oct 05 10:29:34 2019 -0400
+++ b/mercurial/tags.py	Sun Oct 06 09:45:02 2019 -0400
@@ -30,9 +30,7 @@
     scmutil,
     util,
 )
-from .utils import (
-    stringutil,
-)
+from .utils import stringutil
 
 # Tags computation can be expensive and caches exist to make it fast in
 # the common case.
@@ -83,6 +81,7 @@
 # The most recent changeset (in terms of revlog ordering for the head
 # setting it) for each tag is last.
 
+
 def fnoderevs(ui, repo, revs):
     """return the list of '.hgtags' fnodes used in a set revisions
 
@@ -95,6 +94,7 @@
     fnodes = _filterfnodes(fnodes, nodes)
     return fnodes
 
+
 def _nulltonone(value):
     """convert nullid to None
 
@@ -104,6 +104,7 @@
         return None
     return value
 
+
 def difftags(ui, repo, oldfnodes, newfnodes):
     """list differences between tags expressed in two set of file-nodes
 
@@ -134,6 +135,7 @@
     entries.sort()
     return entries
 
+
 def writediff(fp, difflist):
     """write tags diff information to a file.
 
@@ -172,6 +174,7 @@
             fp.write(updateold % (old, tag))
             fp.write(updatenew % (new, tag))
 
+
 def findglobaltags(ui, repo):
     '''Find global tags in a repo: return a tagsmap
 
@@ -190,8 +193,9 @@
         return alltags
 
     for head in reversed(heads):  # oldest to newest
-        assert head in repo.changelog.nodemap, (
-               "tag cache returned bogus head %s" % short(head))
+        assert (
+            head in repo.changelog.nodemap
+        ), "tag cache returned bogus head %s" % short(head)
     fnodes = _filterfnodes(tagfnode, reversed(heads))
     alltags = _tagsfromfnodes(ui, repo, fnodes)
 
@@ -200,6 +204,7 @@
         _writetagcache(ui, repo, valid, alltags)
     return alltags
 
+
 def _filterfnodes(tagfnode, nodes):
     """return a list of unique fnodes
 
@@ -215,6 +220,7 @@
             fnodes.append(fnode)
     return fnodes
 
+
 def _tagsfromfnodes(ui, repo, fnodes):
     """return a tagsmap from a list of file-node
 
@@ -232,6 +238,7 @@
         _updatetags(filetags, alltags)
     return alltags
 
+
 def readlocaltags(ui, repo, alltags, tagtypes):
     '''Read local tags in repo. Update alltags and tagtypes.'''
     try:
@@ -244,8 +251,8 @@
     # localtags is in the local encoding; re-encode to UTF-8 on
     # input for consistency with the rest of this module.
     filetags = _readtags(
-        ui, repo, data.splitlines(), "localtags",
-        recode=encoding.fromlocal)
+        ui, repo, data.splitlines(), "localtags", recode=encoding.fromlocal
+    )
 
     # remove tags pointing to invalid nodes
     cl = repo.changelog
@@ -257,6 +264,7 @@
 
     _updatetags(filetags, alltags, 'local', tagtypes)
 
+
 def _readtaghist(ui, repo, lines, fn, recode=None, calcnodelines=False):
     '''Read tag definitions from a file (or any source of lines).
 
@@ -314,6 +322,7 @@
         bintaghist[name].append(nodebin)
     return bintaghist, hextaglines
 
+
 def _readtags(ui, repo, lines, fn, recode=None, calcnodelines=False):
     '''Read tag definitions from a file (or any source of lines).
 
@@ -323,8 +332,9 @@
     is the list of node ids previously associated with it (in file order).
     All node ids are binary, not hex.
     '''
-    filetags, nodelines = _readtaghist(ui, repo, lines, fn, recode=recode,
-                                       calcnodelines=calcnodelines)
+    filetags, nodelines = _readtaghist(
+        ui, repo, lines, fn, recode=recode, calcnodelines=calcnodelines
+    )
     # util.sortdict().__setitem__ is much slower at replacing then inserting
     # new entries. The difference can matter if there are thousands of tags.
     # Create a new sortdict to avoid the performance penalty.
@@ -333,6 +343,7 @@
         newtags[tag] = (taghist[-1], taghist[:-1])
     return newtags
 
+
 def _updatetags(filetags, alltags, tagtype=None, tagtypes=None):
     """Incorporate the tag info read from one file into dictionnaries
 
@@ -357,14 +368,18 @@
         # otherwise we win because we're tip-most
         anode, ahist = nodehist
         bnode, bhist = alltags[name]
-        if (bnode != anode and anode in bhist and
-            (bnode not in ahist or len(bhist) > len(ahist))):
+        if (
+            bnode != anode
+            and anode in bhist
+            and (bnode not in ahist or len(bhist) > len(ahist))
+        ):
             anode = bnode
         elif tagtype is not None:
             tagtypes[name] = tagtype
         ahist.extend([n for n in bhist if n not in ahist])
         alltags[name] = anode, ahist
 
+
 def _filename(repo):
     """name of a tagcache file for a given repo or repoview"""
     filename = 'tags2'
@@ -372,6 +387,7 @@
         filename = '%s-%s' % (filename, repo.filtername)
     return filename
 
+
 def _readtagcache(ui, repo):
     '''Read the tag cache.
 
@@ -419,14 +435,16 @@
     # (Unchanged tip trivially means no changesets have been added.
     # But, thanks to localrepository.destroyed(), it also means none
     # have been destroyed by strip or rollback.)
-    if (cacherev == tiprev
-            and cachenode == tipnode
-            and cachehash == scmutil.filteredhash(repo, tiprev)):
+    if (
+        cacherev == tiprev
+        and cachenode == tipnode
+        and cachehash == scmutil.filteredhash(repo, tiprev)
+    ):
         tags = _readtags(ui, repo, cachelines, cachefile.name)
         cachefile.close()
         return (None, None, None, tags, False)
     if cachefile:
-        cachefile.close()               # ignore rest of file
+        cachefile.close()  # ignore rest of file
 
     valid = (tiprev, tipnode, scmutil.filteredhash(repo, tiprev))
 
@@ -454,7 +472,6 @@
         # potentially expensive search.
         return ([], {}, valid, None, True)
 
-
     # Now we have to lookup the .hgtags filenode for every new head.
     # This is the most expensive part of finding tags, so performance
     # depends primarily on the size of newheads.  Worst case: no cache
@@ -466,6 +483,7 @@
     # cachefnode to get to each .hgtags revision quickly.
     return (repoheads, cachefnode, valid, None, True)
 
+
 def _getfnodes(ui, repo, nodes):
     """return .hgtags fnodes for a list of changeset nodes
 
@@ -483,11 +501,16 @@
     fnodescache.write()
 
     duration = util.timer() - starttime
-    ui.log('tagscache',
-           '%d/%d cache hits/lookups in %0.4f seconds\n',
-           fnodescache.hitcount, fnodescache.lookupcount, duration)
+    ui.log(
+        'tagscache',
+        '%d/%d cache hits/lookups in %0.4f seconds\n',
+        fnodescache.hitcount,
+        fnodescache.lookupcount,
+        duration,
+    )
     return cachefnode
 
+
 def _writetagcache(ui, repo, valid, cachetags):
     filename = _filename(repo)
     try:
@@ -495,8 +518,12 @@
     except (OSError, IOError):
         return
 
-    ui.log('tagscache', 'writing .hg/cache/%s with %d tags\n',
-           filename, len(cachetags))
+    ui.log(
+        'tagscache',
+        'writing .hg/cache/%s with %d tags\n',
+        filename,
+        len(cachetags),
+    )
 
     if valid[2]:
         cachefile.write('%d %s %s\n' % (valid[0], hex(valid[1]), hex(valid[2])))
@@ -517,6 +544,7 @@
     except (OSError, IOError):
         pass
 
+
 def tag(repo, names, node, message, local, user, date, editor=False):
     '''tag a revision with one or more symbolic names.
 
@@ -541,26 +569,30 @@
     if not local:
         m = matchmod.exact(['.hgtags'])
         if any(repo.status(match=m, unknown=True, ignored=True)):
-            raise error.Abort(_('working copy of .hgtags is changed'),
-                             hint=_('please commit .hgtags manually'))
+            raise error.Abort(
+                _('working copy of .hgtags is changed'),
+                hint=_('please commit .hgtags manually'),
+            )
 
     with repo.wlock():
-        repo.tags() # instantiate the cache
-        _tag(repo, names, node, message, local, user, date,
-             editor=editor)
+        repo.tags()  # instantiate the cache
+        _tag(repo, names, node, message, local, user, date, editor=editor)
+
 
-def _tag(repo, names, node, message, local, user, date, extra=None,
-         editor=False):
+def _tag(
+    repo, names, node, message, local, user, date, extra=None, editor=False
+):
     if isinstance(names, bytes):
         names = (names,)
 
     branches = repo.branchmap()
     for name in names:
-        repo.hook('pretag', throw=True, node=hex(node), tag=name,
-                  local=local)
+        repo.hook('pretag', throw=True, node=hex(node), tag=name, local=local)
         if name in branches:
-            repo.ui.warn(_("warning: tag %s conflicts with existing"
-            " branch name\n") % name)
+            repo.ui.warn(
+                _("warning: tag %s conflicts with existing" " branch name\n")
+                % name
+            )
 
     def writetags(fp, names, munge, prevtags):
         fp.seek(0, io.SEEK_END)
@@ -572,8 +604,7 @@
             else:
                 m = name
 
-            if (repo._tagscache.tagtypes and
-                name in repo._tagscache.tagtypes):
+            if repo._tagscache.tagtypes and name in repo._tagscache.tagtypes:
                 old = repo.tags().get(name, nullid)
                 fp.write('%s %s\n' % (hex(old), m))
             fp.write('%s %s\n' % (hex(node), m))
@@ -614,18 +645,21 @@
         repo[None].add(['.hgtags'])
 
     m = matchmod.exact(['.hgtags'])
-    tagnode = repo.commit(message, user, date, extra=extra, match=m,
-                          editor=editor)
+    tagnode = repo.commit(
+        message, user, date, extra=extra, match=m, editor=editor
+    )
 
     for name in names:
         repo.hook('tag', node=hex(node), tag=name, local=local)
 
     return tagnode
 
+
 _fnodescachefile = 'hgtagsfnodes1'
-_fnodesrecsize = 4 + 20 # changeset fragment + filenode
+_fnodesrecsize = 4 + 20  # changeset fragment + filenode
 _fnodesmissingrec = '\xff' * 24
 
+
 class hgtagsfnodescache(object):
     """Persistent cache mapping revisions to .hgtags filenodes.
 
@@ -645,6 +679,7 @@
     Instances behave like lists. ``c[i]`` works where i is a rev or
     changeset node. Missing indexes are populated automatically on access.
     """
+
     def __init__(self, repo):
         assert repo.filtername is None
 
@@ -654,7 +689,6 @@
         self.lookupcount = 0
         self.hitcount = 0
 
-
         try:
             data = repo.cachevfs.read(_fnodescachefile)
         except (OSError, IOError):
@@ -703,7 +737,7 @@
         self.lookupcount += 1
 
         offset = rev * _fnodesrecsize
-        record = '%s' % self._raw[offset:offset + _fnodesrecsize]
+        record = '%s' % self._raw[offset : offset + _fnodesrecsize]
         properprefix = node[0:4]
 
         # Validate and return existing entry.
@@ -766,7 +800,7 @@
     def _writeentry(self, offset, prefix, fnode):
         # Slices on array instances only accept other array.
         entry = bytearray(prefix + fnode)
-        self._raw[offset:offset + _fnodesrecsize] = entry
+        self._raw[offset : offset + _fnodesrecsize] = entry
         # self._dirtyoffset could be None.
         self._dirtyoffset = min(self._dirtyoffset or 0, offset or 0)
 
@@ -779,7 +813,7 @@
         if self._dirtyoffset is None:
             return
 
-        data = self._raw[self._dirtyoffset:]
+        data = self._raw[self._dirtyoffset :]
         if not data:
             return
 
@@ -788,8 +822,11 @@
         try:
             lock = repo.wlock(wait=False)
         except error.LockError:
-            repo.ui.log('tagscache', 'not writing .hg/cache/%s because '
-                        'lock cannot be acquired\n' % (_fnodescachefile))
+            repo.ui.log(
+                'tagscache',
+                'not writing .hg/cache/%s because '
+                'lock cannot be acquired\n' % _fnodescachefile,
+            )
             return
 
         try:
@@ -799,19 +836,23 @@
                 actualoffset = f.tell()
                 if actualoffset < self._dirtyoffset:
                     self._dirtyoffset = actualoffset
-                    data = self._raw[self._dirtyoffset:]
+                    data = self._raw[self._dirtyoffset :]
                 f.seek(self._dirtyoffset)
                 f.truncate()
-                repo.ui.log('tagscache',
-                            'writing %d bytes to cache/%s\n' % (
-                            len(data), _fnodescachefile))
+                repo.ui.log(
+                    'tagscache',
+                    'writing %d bytes to cache/%s\n'
+                    % (len(data), _fnodescachefile),
+                )
                 f.write(data)
                 self._dirtyoffset = None
             finally:
                 f.close()
         except (IOError, OSError) as inst:
-            repo.ui.log('tagscache',
-                        "couldn't write cache/%s: %s\n" % (
-                            _fnodescachefile, stringutil.forcebytestr(inst)))
+            repo.ui.log(
+                'tagscache',
+                "couldn't write cache/%s: %s\n"
+                % (_fnodescachefile, stringutil.forcebytestr(inst)),
+            )
         finally:
             lock.release()