Mercurial > public > mercurial-scm > hg
comparison mercurial/context.py @ 50130:9e1debbb477e
status: simplify the post status fixup phases
With the wlock automatically discarding changes when applicable, we can
simplify the code a bit.
* we perform the fixup operation before trying to grab the lock to narrow the `try/except`
* we no longer need to explicitly complare dirstate identities. We can trust
the dirstate internal refresh for that. It would invalidate dirty data when
needed.
* detect still data invalidation by checking the dirty flag before and after
taking the lock. Doing this is actually only necessary to issue the debug
message, we could blindy trust the dirstate internal to ignore the `write`
call on a non-dirty dirstate.
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Tue, 21 Feb 2023 16:20:11 +0100 |
parents | 1f369ca9e34c |
children | e5f5f1c1c452 |
comparison
equal
deleted
inserted
replaced
50129:3c6546b149ed | 50130:9e1debbb477e |
---|---|
1852 | 1852 |
1853 return modified, deleted, clean, fixup | 1853 return modified, deleted, clean, fixup |
1854 | 1854 |
1855 def _poststatusfixup(self, status, fixup): | 1855 def _poststatusfixup(self, status, fixup): |
1856 """update dirstate for files that are actually clean""" | 1856 """update dirstate for files that are actually clean""" |
1857 dirstate = self._repo.dirstate | |
1857 poststatus = self._repo.postdsstatus() | 1858 poststatus = self._repo.postdsstatus() |
1858 if fixup or poststatus or self._repo.dirstate._dirty: | 1859 if fixup: |
1860 if dirstate.is_changing_parents: | |
1861 normal = lambda f, pfd: dirstate.update_file( | |
1862 f, | |
1863 p1_tracked=True, | |
1864 wc_tracked=True, | |
1865 ) | |
1866 else: | |
1867 normal = dirstate.set_clean | |
1868 for f, pdf in fixup: | |
1869 normal(f, pdf) | |
1870 if poststatus or self._repo.dirstate._dirty: | |
1859 try: | 1871 try: |
1860 oldid = self._repo.dirstate.identity() | |
1861 | |
1862 # updating the dirstate is optional | 1872 # updating the dirstate is optional |
1863 # so we don't wait on the lock | 1873 # so we don't wait on the lock |
1864 # wlock can invalidate the dirstate, so cache normal _after_ | 1874 # wlock can invalidate the dirstate, so cache normal _after_ |
1865 # taking the lock | 1875 # taking the lock |
1876 pre_dirty = dirstate._dirty | |
1866 with self._repo.wlock(False): | 1877 with self._repo.wlock(False): |
1867 dirstate = self._repo.dirstate | 1878 assert self._repo.dirstate is dirstate |
1868 if dirstate.identity() == oldid: | 1879 post_dirty = dirstate._dirty |
1869 if fixup: | 1880 if post_dirty: |
1870 if dirstate.is_changing_parents: | |
1871 normal = lambda f, pfd: dirstate.update_file( | |
1872 f, p1_tracked=True, wc_tracked=True | |
1873 ) | |
1874 else: | |
1875 normal = dirstate.set_clean | |
1876 for f, pdf in fixup: | |
1877 normal(f, pdf) | |
1878 # write changes out explicitly, because nesting | |
1879 # wlock at runtime may prevent 'wlock.release()' | |
1880 # after this block from doing so for subsequent | |
1881 # changing files | |
1882 # | |
1883 # (This is outside of the (if fixup) block because the | |
1884 # status operation itself might have updated some cache | |
1885 # information before.) | |
1886 tr = self._repo.currenttransaction() | 1881 tr = self._repo.currenttransaction() |
1887 self._repo.dirstate.write(tr) | 1882 dirstate.write(tr) |
1888 | 1883 elif pre_dirty: |
1889 if poststatus: | 1884 # the wlock grabbing detected that dirtate changes |
1890 for ps in poststatus: | 1885 # needed to be dropped |
1891 ps(self, status) | 1886 m = b'skip updating dirstate: identity mismatch\n' |
1892 else: | 1887 self._repo.ui.debug(m) |
1893 # in this case, writing changes out breaks | 1888 if poststatus: |
1894 # consistency, because .hg/dirstate was | 1889 for ps in poststatus: |
1895 # already changed simultaneously after last | 1890 ps(self, status) |
1896 # caching (see also issue5584 for detail) | |
1897 self._repo.ui.debug( | |
1898 b'skip updating dirstate: identity mismatch\n' | |
1899 ) | |
1900 # throw away anything we have. | |
1901 dirstate.invalidate() | |
1902 except error.LockError: | 1891 except error.LockError: |
1903 pass | 1892 pass |
1904 finally: | 1893 finally: |
1905 # 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. |
1906 self._repo.clearpostdsstatus() | 1895 self._repo.clearpostdsstatus() |