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