diff --git a/hgext/mq.py b/hgext/mq.py --- a/hgext/mq.py +++ b/hgext/mq.py @@ -2186,20 +2186,17 @@ def reposetup(ui, repo): return tagscache - def _branchtags(self): + def _branchtags(self, partial, lrev): q = self.mq if not q.applied: - return super(mqrepo, self)._branchtags() + return super(mqrepo, self)._branchtags(partial, lrev) cl = self.changelog qbasenode = revlog.bin(q.applied[0].rev) if qbasenode not in cl.nodemap: self.ui.warn('mq status file refers to unknown node %s\n' % revlog.short(qbasenode)) - return super(mqrepo, self)._branchtags() - - self.branchcache = {} # avoid recursion in changectx - partial, last, lrev = self._readbranchcache() + return super(mqrepo, self)._branchtags(partial, lrev) qbase = cl.rev(qbasenode) start = lrev + 1 diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -94,6 +94,8 @@ class localrepository(repo.repository): self.tagscache = None self._tagstypecache = None self.branchcache = None + self._ubranchcache = None # UTF-8 version of branchcache + self._branchcachetip = None self.nodetagscache = None self.filterpats = {} self._datafilters = {} @@ -344,9 +346,7 @@ class localrepository(repo.repository): self.nodetagscache.setdefault(n, []).append(t) return self.nodetagscache.get(node, []) - def _branchtags(self): - partial, last, lrev = self._readbranchcache() - + def _branchtags(self, partial, lrev): tiprev = self.changelog.count() - 1 if lrev != tiprev: self._updatebranchcache(partial, lrev+1, tiprev+1) @@ -355,16 +355,29 @@ class localrepository(repo.repository): return partial def branchtags(self): - if self.branchcache is not None: + tip = self.changelog.tip() + if self.branchcache is not None and self._branchcachetip == tip: return self.branchcache - self.branchcache = {} # avoid recursion in changectx - partial = self._branchtags() + oldtip = self._branchcachetip + self._branchcachetip = tip + if self.branchcache is None: + self.branchcache = {} # avoid recursion in changectx + else: + self.branchcache.clear() # keep using the same dict + if oldtip is None or oldtip not in self.changelog.nodemap: + partial, last, lrev = self._readbranchcache() + else: + lrev = self.changelog.rev(oldtip) + partial = self._ubranchcache + + self._branchtags(partial, lrev) # the branch cache is stored on disk as UTF-8, but in the local # charset internally for k, v in partial.items(): self.branchcache[util.tolocal(k)] = v + self._ubranchcache = partial return self.branchcache def _readbranchcache(self): @@ -616,6 +629,9 @@ class localrepository(repo.repository): self.tagscache = None self._tagstypecache = None self.nodetagscache = None + self.branchcache = None + self._ubranchcache = None + self._branchcachetip = None def _lock(self, lockname, wait, releasefn, acquirefn, desc): try: @@ -882,8 +898,8 @@ class localrepository(repo.repository): parent2=xp2) tr.close() - if self.branchcache and "branch" in extra: - self.branchcache[util.tolocal(extra["branch"])] = n + if self.branchcache: + self.branchtags() if use_dirstate or update_dirstate: self.dirstate.setparents(n) @@ -2005,7 +2021,6 @@ class localrepository(repo.repository): if changesets > 0: # forcefully update the on-disk branch cache self.ui.debug(_("updating the branch cache\n")) - self.branchcache = None self.branchtags() self.hook("changegroup", node=hex(self.changelog.node(cor+1)), source=srctype, url=url)