Mercurial > public > mercurial-scm > hg-stable
comparison 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 |
comparison
equal
deleted
inserted
replaced
32771:627eaab1ad07 | 32772:dc7efa2826e4 |
---|---|
1757 deleted.append(f) | 1757 deleted.append(f) |
1758 | 1758 |
1759 # update dirstate for files that are actually clean | 1759 # update dirstate for files that are actually clean |
1760 if fixup: | 1760 if fixup: |
1761 try: | 1761 try: |
1762 oldid = self._repo.dirstate.identity() | |
1763 | |
1762 # updating the dirstate is optional | 1764 # updating the dirstate is optional |
1763 # so we don't wait on the lock | 1765 # so we don't wait on the lock |
1764 # wlock can invalidate the dirstate, so cache normal _after_ | 1766 # wlock can invalidate the dirstate, so cache normal _after_ |
1765 # taking the lock | 1767 # taking the lock |
1766 with self._repo.wlock(False): | 1768 with self._repo.wlock(False): |
1767 normal = self._repo.dirstate.normal | 1769 if self._repo.dirstate.identity() == oldid: |
1768 for f in fixup: | 1770 normal = self._repo.dirstate.normal |
1769 normal(f) | 1771 for f in fixup: |
1770 # write changes out explicitly, because nesting | 1772 normal(f) |
1771 # wlock at runtime may prevent 'wlock.release()' | 1773 # write changes out explicitly, because nesting |
1772 # after this block from doing so for subsequent | 1774 # wlock at runtime may prevent 'wlock.release()' |
1773 # changing files | 1775 # after this block from doing so for subsequent |
1774 self._repo.dirstate.write(self._repo.currenttransaction()) | 1776 # changing files |
1777 tr = self._repo.currenttransaction() | |
1778 self._repo.dirstate.write(tr) | |
1779 else: | |
1780 # in this case, writing changes out breaks | |
1781 # consistency, because .hg/dirstate was | |
1782 # already changed simultaneously after last | |
1783 # caching (see also issue5584 for detail) | |
1784 self._repo.ui.debug('skip updating dirstate: ' | |
1785 'identity mismatch\n') | |
1775 except error.LockError: | 1786 except error.LockError: |
1776 pass | 1787 pass |
1777 return modified, deleted, fixup | 1788 return modified, deleted, fixup |
1778 | 1789 |
1779 def _dirstatestatus(self, match=None, ignored=False, clean=False, | 1790 def _dirstatestatus(self, match=None, ignored=False, clean=False, |