Mercurial > hg
changeset 32815:15e85dded933
fsmonitor: write state with wlock held and dirstate unchanged (issue5581)
This means that the state will not be written if:
(1) either the wlock can't be obtained
(2) something else came along and changed the dirstate while we were in the
middle of a status run.
author | Siddharth Agarwal <sid0@fb.com> |
---|---|
date | Mon, 12 Jun 2017 15:34:31 -0700 |
parents | 2083d1643d69 |
children | 1b25c648d5b7 |
files | hgext/fsmonitor/__init__.py tests/test-dirstate-race.t |
diffstat | 2 files changed, 62 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/hgext/fsmonitor/__init__.py Mon Jun 12 13:56:50 2017 -0700 +++ b/hgext/fsmonitor/__init__.py Mon Jun 12 15:34:31 2017 -0700 @@ -485,17 +485,14 @@ else: stateunknown = listunknown + if updatestate: + ps = poststatus(startclock) + self.addpostdsstatus(ps) + r = orig(node1, node2, match, listignored, listclean, stateunknown, listsubrepos) modified, added, removed, deleted, unknown, ignored, clean = r - if updatestate: - notefiles = modified + added + removed + deleted + unknown - self._fsmonitorstate.set( - self._fsmonitorstate.getlastclock() or startclock, - _hashignore(self.dirstate._ignore), - notefiles) - if not listunknown: unknown = [] @@ -528,6 +525,17 @@ return scmutil.status( modified, added, removed, deleted, unknown, ignored, clean) +class poststatus(object): + def __init__(self, startclock): + self._startclock = startclock + + def __call__(self, wctx, status): + clock = wctx.repo()._fsmonitorstate.getlastclock() or self._startclock + hashignore = _hashignore(wctx.repo().dirstate._ignore) + notefiles = (status.modified + status.added + status.removed + + status.deleted + status.unknown) + wctx.repo()._fsmonitorstate.set(clock, hashignore, notefiles) + def makedirstate(cls): class fsmonitordirstate(cls): def _fsmonitorinit(self, fsmonitorstate, watchmanclient):
--- a/tests/test-dirstate-race.t Mon Jun 12 13:56:50 2017 -0700 +++ b/tests/test-dirstate-race.t Mon Jun 12 15:34:31 2017 -0700 @@ -157,3 +157,50 @@ a $ hg debugdirstate n * * * a (glob) + + $ rm b + +Set up a rebase situation for issue5581. + + $ echo c2 > a + $ echo c2 > b + $ hg add b + $ hg commit -m c2 + created new head + $ echo c3 >> a + $ hg commit -m c3 + $ hg update 2 + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ echo c4 >> a + $ echo c4 >> b + $ hg commit -m c4 + created new head + +Configure a merge tool that runs status in the middle of the rebase. + + $ cat >> $TESTTMP/mergetool-race.sh << EOF + > echo "custom merge tool" + > printf "c2\nc3\nc4\n" > \$1 + > hg --cwd $TESTTMP/repo status + > echo "custom merge tool end" + > EOF + $ cat >> $HGRCPATH << EOF + > [extensions] + > rebase = + > [merge-tools] + > test.executable=sh + > test.args=$TESTTMP/mergetool-race.sh \$output + > EOF + + $ hg rebase -s . -d 3 --tool test + rebasing 4:b08445fd6b2a "c4" (tip) + merging a + custom merge tool + M a + ? a.orig + custom merge tool end + saved backup bundle to $TESTTMP/repo/.hg/strip-backup/* (glob) + +This hg status should be empty, whether or not fsmonitor is enabled (issue5581). + + $ hg status