comparison mercurial/context.py @ 50131:e5f5f1c1c452

status: invalidate dirstate on LockError If we cannot take the lock, someone else is modifying the repository. Let us discard dirstate uncommitted data before exiting the status code. Having a clean dirstate after such operation seems safer. Strictly speaking, there is a small behavior change in the following situation: * process A call `status` outside of the `wlock` * process B grab the `wlock` * process A fails to acquires the lock to write status fixup * process B release the `wlock` *without touching the dirstate* * process A later grab the `wlock` * process A can write dirstate update from earlier `status` However this is a fairly hypothetical situation : * process A has to be raced * process B have to not update the dirstate * process A has to run another *unrelated* operation later. This seems rare enough to overlook. I am stating that the two operations in process A has to be unrelated. Otherwise, collecting status data outside of the lock to use them inside the lock is racy. Any other process could move things around (eg: the working copy) making the data collected during status irrelevantor even harmful. If such code exists, it should be fixed ASAP.
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Tue, 21 Feb 2023 22:14:12 +0100
parents 9e1debbb477e
children 21b6ce3ade35
comparison
equal deleted inserted replaced
50130:9e1debbb477e 50131:e5f5f1c1c452
1887 self._repo.ui.debug(m) 1887 self._repo.ui.debug(m)
1888 if poststatus: 1888 if poststatus:
1889 for ps in poststatus: 1889 for ps in poststatus:
1890 ps(self, status) 1890 ps(self, status)
1891 except error.LockError: 1891 except error.LockError:
1892 pass 1892 dirstate.invalidate()
1893 finally: 1893 finally:
1894 # Even if the wlock couldn't be grabbed, clear out the list. 1894 # Even if the wlock couldn't be grabbed, clear out the list.
1895 self._repo.clearpostdsstatus() 1895 self._repo.clearpostdsstatus()
1896 1896
1897 def _dirstatestatus(self, match, ignored=False, clean=False, unknown=False): 1897 def _dirstatestatus(self, match, ignored=False, clean=False, unknown=False):