changeset 50723:bfbd84c57bda stable

dirstate-v2: actually fix the dirstate-v2 upgrade race It looks like the previous fix for the dirstate-v2 upgrade race didn't work. The problem is that it only recovers in case the size of the v1 `dirstate` file is smaller than the `v2` one, whereas in real life it's always larger. This commit changes the test to be more realistic, which reveals the crash, and changes the code to fix the crash.
author Arseniy Alekseyev <aalekseyev@janestreet.com>
date Mon, 26 Jun 2023 11:21:43 +0100
parents 42f761e97dec
children a10d823a8e3d
files mercurial/dirstatemap.py tests/test-dirstate-version-fallback.t
diffstat 2 files changed, 7 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/dirstatemap.py	Thu Jun 22 14:24:45 2023 +0200
+++ b/mercurial/dirstatemap.py	Mon Jun 26 11:21:43 2023 +0100
@@ -4,7 +4,6 @@
 # GNU General Public License version 2 or any later version.
 
 
-import struct
 from .i18n import _
 
 from . import (
@@ -152,15 +151,13 @@
                     b'dirstate only has a docket in v2 format'
                 )
             self._set_identity()
-            try:
+            data = self._readdirstatefile()
+            if data == b'' or data.startswith(docketmod.V2_FORMAT_MARKER):
                 self._docket = docketmod.DirstateDocket.parse(
-                    self._readdirstatefile(), self._nodeconstants
+                    data, self._nodeconstants
                 )
-            except struct.error:
-                self._ui.debug(b"failed to read dirstate-v2 data")
-                raise error.CorruptedDirstate(
-                    b"failed to read dirstate-v2 data"
-                )
+            else:
+                raise error.CorruptedDirstate(b"dirstate is not in v2 format")
         return self._docket
 
     def _read_v2_data(self):
--- a/tests/test-dirstate-version-fallback.t	Thu Jun 22 14:24:45 2023 +0200
+++ b/tests/test-dirstate-version-fallback.t	Mon Jun 26 11:21:43 2023 +0100
@@ -10,8 +10,8 @@
   $ hg init repo
   $ cd repo
   $ echo a > a
-  $ hg add a
-  $ hg commit -m a
+  $ touch file-with-somewhat-long-name-to-make-dirstate-v1-bigger-than-v2
+  $ hg commit -Aqm a
   $ hg debugrequires | grep dirstate
   [1]
   $ ls -1 .hg/dirstate*