# HG changeset patch # User Pierre-Yves David # Date 1643725190 -3600 # Node ID 8e5effbf52d03e599aed568ff24e053d140f2f43 # Parent 3f618484eeb60467988cd97f18edc61ff18e486e branchmap: stop writing cache for uncommitted data If we are about to write the branch while a transaction is active. we delay that write. After the transaction is closed, we flush all the write we delayed (unless they have been written in between). Differential Revision: https://phab.mercurial-scm.org/D12128 diff -r 3f618484eeb6 -r 8e5effbf52d0 mercurial/branchmap.py --- a/mercurial/branchmap.py Mon Jan 31 19:28:58 2022 +0100 +++ b/mercurial/branchmap.py Tue Feb 01 15:19:50 2022 +0100 @@ -149,6 +149,13 @@ def clear(self): self._per_filter.clear() + def write_delayed(self, repo): + unfi = repo.unfiltered() + for filtername, cache in self._per_filter.items(): + if cache._delayed: + repo = unfi.filtered(filtername) + cache.write(repo) + def _unknownnode(node): """raises ValueError when branchcache found a node which does not exists""" @@ -199,6 +206,7 @@ has a given node or not. If it's not provided, we assume that every node we have exists in changelog""" self._repo = repo + self._delayed = False if tipnode is None: self.tipnode = repo.nullid else: @@ -403,6 +411,13 @@ ) def write(self, repo): + tr = repo.currenttransaction() + if not getattr(tr, 'finalized', True): + # Avoid premature writing. + # + # (The cache warming setup by localrepo will update the file later.) + self._delayed = True + return try: f = repo.cachevfs(self._filename(repo), b"w", atomictemp=True) cachekey = [hex(self.tipnode), b'%d' % self.tiprev] @@ -427,6 +442,7 @@ len(self._entries), nodecount, ) + self._delayed = False except (IOError, OSError, error.Abort) as inst: # Abort may be raised by read only opener, so log and continue repo.ui.debug( diff -r 3f618484eeb6 -r 8e5effbf52d0 mercurial/localrepo.py --- a/mercurial/localrepo.py Mon Jan 31 19:28:58 2022 +0100 +++ b/mercurial/localrepo.py Tue Feb 01 15:19:50 2022 +0100 @@ -2830,6 +2830,8 @@ self.ui.debug(b'updating the branch cache\n') self.filtered(b'served').branchmap() self.filtered(b'served.hidden').branchmap() + # flush all possibly delayed write. + self._branchcaches.write_delayed(self) if repository.CACHE_CHANGELOG_CACHE in caches: self.changelog.update_caches(transaction=tr) diff -r 3f618484eeb6 -r 8e5effbf52d0 tests/test-branches.t --- a/tests/test-branches.t Mon Jan 31 19:28:58 2022 +0100 +++ b/tests/test-branches.t Tue Feb 01 15:19:50 2022 +0100 @@ -1336,7 +1336,5 @@ abort: pretxnclose hook failed [40] $ cat branchmap-update-02/.hg/cache/branch2-served - 99ba08759bc7f6fdbe5304e83d0387f35c082479 1 (missing-correct-output !) - 99ba08759bc7f6fdbe5304e83d0387f35c082479 o A (missing-correct-output !) - 71ca9a6d524ed3c2a215119b2086ac3b8c4c8286 3 (known-bad-output !) - 71ca9a6d524ed3c2a215119b2086ac3b8c4c8286 o A (known-bad-output !) + 99ba08759bc7f6fdbe5304e83d0387f35c082479 1 + 99ba08759bc7f6fdbe5304e83d0387f35c082479 o A