# HG changeset patch # User Pierre-Yves David # Date 1677607280 -3600 # Node ID a3b1ab5f5deeaf0a10fc2483220a4fab751c87df # Parent 53f19662269970b8a77aa68755a86a0bfe5a8c00 dirstate: deal with read-race for pure python code If we cannot read the dirstate data, this is probably because a writing process wrote it under our feet. So refresh the docket and try again a handful of time. diff -r 53f196622699 -r a3b1ab5f5dee mercurial/dirstatemap.py --- a/mercurial/dirstatemap.py Wed Mar 01 16:05:28 2023 +0100 +++ b/mercurial/dirstatemap.py Tue Feb 28 19:01:20 2023 +0100 @@ -37,6 +37,9 @@ WRITE_MODE_FORCE_APPEND = 2 +V2_MAX_READ_ATTEMPTS = 5 + + class _dirstatemapcommon: """ Methods that are identical for both implementations of the dirstatemap @@ -125,6 +128,21 @@ return self._docket def _read_v2_data(self): + data = None + attempts = 0 + while attempts < V2_MAX_READ_ATTEMPTS: + attempts += 1 + try: + data = self._opener.read(self.docket.data_filename()) + except FileNotFoundError: + # read race detected between docket and data file + # reload the docket and retry + self._docket = None + if data is None: + assert attempts >= V2_MAX_READ_ATTEMPTS + msg = b"dirstate read race happened %d times in a row" + msg %= attempts + raise error.Abort(msg) return self._opener.read(self.docket.data_filename()) def write_v2_no_append(self, tr, st, meta, packed): diff -r 53f196622699 -r a3b1ab5f5dee tests/test-dirstate-read-race.t --- a/tests/test-dirstate-read-race.t Wed Mar 01 16:05:28 2023 +0100 +++ b/tests/test-dirstate-read-race.t Tue Feb 28 19:01:20 2023 +0100 @@ -217,8 +217,12 @@ #endif #else $ cat $TESTTMP/status-race-lock.out + A dir/n + A dir/o + R dir/nested/m + ? p + ? q $ cat $TESTTMP/status-race-lock.log - abort: $ENOENT$: '$TESTTMP/race-with-add/.hg/dirstate.* (glob) #endif #endif #endif @@ -318,8 +322,12 @@ #endif #else $ cat $TESTTMP/status-race-lock.out + M dir/o + ? dir/n + ? p + ? q $ cat $TESTTMP/status-race-lock.log - abort: $ENOENT$: '$TESTTMP/race-with-commit/.hg/dirstate.* (glob) + warning: ignoring unknown working parent 02a67a77ee9b! #endif #endif #endif @@ -452,8 +460,11 @@ #endif #else $ cat $TESTTMP/status-race-lock.out + A dir/o + ? dir/n + ? p + ? q $ cat $TESTTMP/status-race-lock.log - abort: $ENOENT$: '$TESTTMP/race-with-update/.hg/dirstate.* (glob) #endif #endif #endif @@ -542,8 +553,12 @@ #endif #else $ cat $TESTTMP/status-race-lock.out + A dir/o + R dir/nested/m + ? dir/n + ? p + ? q $ cat $TESTTMP/status-race-lock.log - abort: $ENOENT$: '$TESTTMP/race-with-status/.hg/dirstate.* (glob) #endif #endif #endif