changeset 52961:51a9148f8349 stable

dirstate-race: fix a missing synchronisation in the python code This was giving the wrong output in the `dirstate-v2-rewrite` case. As the dirstate is rewritten, the data file is missing and we reload the full dirstate. The make the dirstate reloaded after the commit and it no longer see the file as dirty. Note that if we were deleting the data file less aggressively, we would see the other output. (for example if we were keeping old data file around for some time before deletion). One last thing? fixing this reveal a quite serious bug where a `hg status` end up overwriting a `hg update` done concurrently. Hooray for proper testing.
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Tue, 18 Feb 2025 03:28:20 +0100
parents 565191843567
children e16065bb7f42
files mercurial/dirstatemap.py tests/test-dirstate-read-race.t
diffstat 2 files changed, 29 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/dirstatemap.py	Tue Feb 18 09:35:23 2025 +0100
+++ b/mercurial/dirstatemap.py	Tue Feb 18 03:28:20 2025 +0100
@@ -197,6 +197,7 @@
                 )
             else:
                 raise error.CorruptedDirstate(b"dirstate is not in v2 format")
+            testing.wait_on_cfg(self._ui, b'dirstate.post-docket-read-file')
         return self._docket
 
     def _read_v2_data(self):
--- a/tests/test-dirstate-read-race.t	Tue Feb 18 09:35:23 2025 +0100
+++ b/tests/test-dirstate-read-race.t	Tue Feb 18 03:28:20 2025 +0100
@@ -231,11 +231,13 @@
 
 The status process should return a consistent result and not crash.
 
+(The "pre-commit" state is only visible to (any) rust variant because the pure
+python implementation always rewrites, so we are never really in the "-append"
+case).
+
   $ cat $TESTTMP/status-race-lock.out
-  A dir/o (no-dirstate-v1 pre-some-read no-rhg !)
-  R dir/nested/m (no-dirstate-v1 pre-some-read no-rhg !)
-  A dir/o (dirstate-v2-append pre-some-read rhg !)
-  R dir/nested/m (dirstate-v2-append pre-some-read rhg !)
+  A dir/o (dirstate-v2-append pre-some-read rust !)
+  R dir/nested/m (dirstate-v2-append pre-some-read rust !)
   ? dir/n
   ? p
   ? q
@@ -282,6 +284,27 @@
   $ touch $TESTTMP/status-race-lock
   $ wait
 (the working copy should have been updated)
+#if rust no-rhg known-bad-output dirstate-v2-append pre-some-read known-bad-output
+  $ hg log -T '{node|short}\n' --rev "."
+  9a86dcbfb938
+  $ hg log -GT '{node|short} {desc}\n'
+  @  9a86dcbfb938 more files to have two commit
+  |
+  o  4f23db756b09 recreate a bunch of files to facilitate dirstate-v2 append
+  
+  $ hg status
+  A dir/o
+  R dir/nested/m
+  ! dir/i
+  ! dir/j
+  ! dir/nested/h
+  ! dir2/k
+  ! dir2/l
+  ! g
+  ? dir/n
+  ? p
+  ? q
+#else
   $ hg log -T '{node|short}\n' --rev "."
   4f23db756b09
   $ hg log -GT '{node|short} {desc}\n'
@@ -294,6 +317,7 @@
   ? dir/n
   ? p
   ? q
+#endif
 
 The status process should return a consistent result and not crash.