Mercurial > public > mercurial-scm > hg
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.