Mercurial > public > mercurial-scm > hg-stable
diff mercurial/context.py @ 32772:dc7efa2826e4
context: avoid writing outdated dirstate out (issue5584)
Before this patch, workingctx.status() may cause writing outdated
dirstate out, if:
- .hg/dirstate is changed simultaneously after last loading it,
- there is any file, which should be dirstate.normal()-ed
Typical issue case is:
- the working directory is updated by "hg update"
- .hg/dirstate is updated in background (e.g. fsmonitor)
This patch compares identities of dirstate before and after
acquisition of wlock, and avoids writing outdated dirstate out, if
change of .hg/dirstate is detected.
author | FUJIWARA Katsunori <foozy@lares.dti.ne.jp> |
---|---|
date | Fri, 09 Jun 2017 13:07:49 +0900 |
parents | 3e8eb6d84a5c |
children | 34be21aa2b26 |
line wrap: on
line diff
--- a/mercurial/context.py Fri Jun 09 13:07:49 2017 +0900 +++ b/mercurial/context.py Fri Jun 09 13:07:49 2017 +0900 @@ -1759,19 +1759,30 @@ # update dirstate for files that are actually clean if fixup: try: + oldid = self._repo.dirstate.identity() + # updating the dirstate is optional # so we don't wait on the lock # wlock can invalidate the dirstate, so cache normal _after_ # taking the lock with self._repo.wlock(False): - normal = self._repo.dirstate.normal - for f in fixup: - normal(f) - # write changes out explicitly, because nesting - # wlock at runtime may prevent 'wlock.release()' - # after this block from doing so for subsequent - # changing files - self._repo.dirstate.write(self._repo.currenttransaction()) + if self._repo.dirstate.identity() == oldid: + normal = self._repo.dirstate.normal + for f in fixup: + normal(f) + # write changes out explicitly, because nesting + # wlock at runtime may prevent 'wlock.release()' + # after this block from doing so for subsequent + # changing files + tr = self._repo.currenttransaction() + self._repo.dirstate.write(tr) + else: + # in this case, writing changes out breaks + # consistency, because .hg/dirstate was + # already changed simultaneously after last + # caching (see also issue5584 for detail) + self._repo.ui.debug('skip updating dirstate: ' + 'identity mismatch\n') except error.LockError: pass return modified, deleted, fixup