diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -1738,7 +1738,10 @@ class workingctx(committablectx): # it's in the dirstate. deleted.append(f) - # update dirstate for files that are actually clean + return modified, deleted, fixup + + def _poststatusfixup(self, fixup): + """update dirstate for files that are actually clean""" if fixup: try: oldid = self._repo.dirstate.identity() @@ -1767,7 +1770,6 @@ class workingctx(committablectx): 'identity mismatch\n') except error.LockError: pass - return modified, deleted, fixup def _dirstatestatus(self, match=None, ignored=False, clean=False, unknown=False): @@ -1781,15 +1783,17 @@ class workingctx(committablectx): listclean, listunknown) # check for any possibly clean files + fixup = [] if cmp: modified2, deleted2, fixup = self._checklookup(cmp) s.modified.extend(modified2) s.deleted.extend(deleted2) - # update dirstate for files that are actually clean if fixup and listclean: s.clean.extend(fixup) + self._poststatusfixup(fixup) + if match.always(): # cache for performance if s.unknown or s.ignored or s.clean: diff --git a/tests/fakedirstatewritetime.py b/tests/fakedirstatewritetime.py --- a/tests/fakedirstatewritetime.py +++ b/tests/fakedirstatewritetime.py @@ -2,7 +2,7 @@ # specified by '[fakedirstatewritetime] fakenow', only when # 'dirstate.write()' is invoked via functions below: # -# - 'workingctx._checklookup()' (= 'repo.status()') +# - 'workingctx._poststatusfixup()' (= 'repo.status()') # - 'committablectx.markcommitted()' from __future__ import absolute_import @@ -55,16 +55,16 @@ def fakewrite(ui, func): parsers.pack_dirstate = orig_pack_dirstate dirstate._getfsnow = orig_dirstate_getfsnow -def _checklookup(orig, workingctx, files): +def _poststatusfixup(orig, workingctx, fixup): ui = workingctx.repo().ui - return fakewrite(ui, lambda : orig(workingctx, files)) + return fakewrite(ui, lambda : orig(workingctx, fixup)) def markcommitted(orig, committablectx, node): ui = committablectx.repo().ui return fakewrite(ui, lambda : orig(committablectx, node)) def extsetup(ui): - extensions.wrapfunction(context.workingctx, '_checklookup', - _checklookup) + extensions.wrapfunction(context.workingctx, '_poststatusfixup', + _poststatusfixup) extensions.wrapfunction(context.committablectx, 'markcommitted', markcommitted) diff --git a/tests/test-dirstate-race.t b/tests/test-dirstate-race.t --- a/tests/test-dirstate-race.t +++ b/tests/test-dirstate-race.t @@ -101,7 +101,7 @@ anyway. Test that dirstate changes aren't written out at the end of "hg status", if .hg/dirstate is already changed simultaneously before -acquisition of wlock in workingctx._checklookup(). +acquisition of wlock in workingctx._poststatusfixup(). This avoidance is important to keep consistency of dirstate in race condition (see issue5584 for detail).