D12128: branchmap: stop writing cache for uncommitted data

marmoute (Pierre-Yves David) phabricator at mercurial-scm.org
Tue Feb 1 16:52:46 UTC 2022


marmoute created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  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).

REPOSITORY
  rHG Mercurial

BRANCH
  stable

REVISION DETAIL
  https://phab.mercurial-scm.org/D12128

AFFECTED FILES
  mercurial/branchmap.py
  mercurial/localrepo.py
  tests/test-branches.t

CHANGE DETAILS

diff --git a/tests/test-branches.t b/tests/test-branches.t
--- a/tests/test-branches.t
+++ b/tests/test-branches.t
@@ -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
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -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 --git a/mercurial/branchmap.py b/mercurial/branchmap.py
--- a/mercurial/branchmap.py
+++ b/mercurial/branchmap.py
@@ -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(



To: marmoute, #hg-reviewers
Cc: mercurial-patches, mercurial-devel


More information about the Mercurial-devel mailing list