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.
--- 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*