diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -1517,6 +1517,10 @@ class workingctx(committablectx): try: for f in fixup: normal(f) + # write changes out explicitly, because nesting + # wlock at runtime may prevent 'wlock.release()' + # below from doing so for subsequent changing files + self._repo.dirstate.write() finally: wlock.release() except error.LockError: diff --git a/tests/test-largefiles-misc.t b/tests/test-largefiles-misc.t --- a/tests/test-largefiles-misc.t +++ b/tests/test-largefiles-misc.t @@ -1008,10 +1008,6 @@ largefiles (issue4547) > EOF $ hg clone -q enabled-but-no-largefiles no-largefiles -(test rebasing implied by pull: precommit while rebasing unexpectedly -shows "normal3" as "?", because lfdirstate isn't yet written out at -that time) - $ echo normal2 > enabled-but-no-largefiles/normal2 $ hg -R enabled-but-no-largefiles add enabled-but-no-largefiles/normal2 $ hg -R enabled-but-no-largefiles commit -m '#1@enabled-but-no-largefiles' @@ -1026,7 +1022,7 @@ that time) $ hg -R no-largefiles -q pull --rebase Invoking status precommit hook - M normal3 + A normal3 (test reverting) diff --git a/tests/test-merge-tools.t b/tests/test-merge-tools.t --- a/tests/test-merge-tools.t +++ b/tests/test-merge-tools.t @@ -601,6 +601,17 @@ HGMERGE specifies internal:other but is update is a merge ... +(this also tests that files reverted with '--rev REV' are treated as +"modified", even if none of mode, size and timestamp of them isn't +changed on the filesystem (see also issue4583)) + + $ cat >> $HGRCPATH < [fakedirstatewritetime] + > # emulate invoking dirstate.write() via repo.status() + > # at 2000-01-01 00:00 + > fakenow = 200001010000 + > EOF + $ beforemerge [merge-tools] false.whatever= @@ -611,8 +622,16 @@ update is a merge ... $ f -s f f: size=17 $ touch -t 200001010000 f - $ hg status f + $ hg debugrebuildstate + $ cat >> $HGRCPATH < [extensions] + > fakedirstatewritetime = $TESTDIR/fakedirstatewritetime.py + > EOF $ hg revert -q -r 1 . + $ cat >> $HGRCPATH < [extensions] + > fakedirstatewritetime = ! + > EOF $ f -s f f: size=17 $ touch -t 200001010000 f @@ -646,8 +665,16 @@ update should also have --tool $ f -s f f: size=17 $ touch -t 200001010000 f - $ hg status f + $ hg debugrebuildstate + $ cat >> $HGRCPATH < [extensions] + > fakedirstatewritetime = $TESTDIR/fakedirstatewritetime.py + > EOF $ hg revert -q -r 1 . + $ cat >> $HGRCPATH < [extensions] + > fakedirstatewritetime = ! + > EOF $ f -s f f: size=17 $ touch -t 200001010000 f diff --git a/tests/test-merge1.t b/tests/test-merge1.t --- a/tests/test-merge1.t +++ b/tests/test-merge1.t @@ -206,4 +206,91 @@ Test for issue2364 $ hg revert -r -2 b $ hg up -q -- -2 +Test that updated files are treated as "modified", when +'merge.update()' is aborted before 'merge.recordupdates()' (= parents +aren't changed), even if none of mode, size and timestamp of them +isn't changed on the filesystem (see also issue4583). + + $ cat > $TESTTMP/abort.py < # emulate aborting before "recordupdates()". in this case, files + > # are changed without updating dirstate + > from mercurial import extensions, merge, util + > def applyupdates(orig, *args, **kwargs): + > orig(*args, **kwargs) + > raise util.Abort('intentional aborting') + > def extsetup(ui): + > extensions.wrapfunction(merge, "applyupdates", applyupdates) + > EOF + + $ cat >> .hg/hgrc < [fakedirstatewritetime] + > # emulate invoking dirstate.write() via repo.status() + > # at 2000-01-01 00:00 + > fakenow = 200001010000 + > EOF + +(file gotten from other revision) + + $ hg update -q -C 2 + $ echo 'THIS IS FILE B5' > b + $ hg commit -m 'commit #5' + + $ hg update -q -C 3 + $ cat b + This is file b1 + $ touch -t 200001010000 b + $ hg debugrebuildstate + + $ cat >> .hg/hgrc < [extensions] + > fakedirstatewritetime = $TESTDIR/fakedirstatewritetime.py + > abort = $TESTTMP/abort.py + > EOF + $ hg merge 5 + abort: intentional aborting + [255] + $ cat >> .hg/hgrc < [extensions] + > fakedirstatewritetime = ! + > abort = ! + > EOF + + $ cat b + THIS IS FILE B5 + $ touch -t 200001010000 b + $ hg status -A b + M b + +(file merged from other revision) + + $ hg update -q -C 3 + $ echo 'this is file b6' > b + $ hg commit -m 'commit #6' + created new head + + $ cat b + this is file b6 + $ touch -t 200001010000 b + $ hg debugrebuildstate + + $ cat >> .hg/hgrc < [extensions] + > fakedirstatewritetime = $TESTDIR/fakedirstatewritetime.py + > abort = $TESTTMP/abort.py + > EOF + $ hg merge --tool internal:other 5 + abort: intentional aborting + [255] + $ cat >> .hg/hgrc < [extensions] + > fakedirstatewritetime = ! + > abort = ! + > EOF + + $ cat b + THIS IS FILE B5 + $ touch -t 200001010000 b + $ hg status -A b + M b + $ cd .. diff --git a/tests/test-revert.t b/tests/test-revert.t --- a/tests/test-revert.t +++ b/tests/test-revert.t @@ -175,6 +175,46 @@ revert of exec bit executable #endif +Test that files reverted to other than the parent are treated as +"modified", even if none of mode, size and timestamp of it isn't +changed on the filesystem (see also issue4583). + + $ echo 321 > e + $ hg diff --git + diff --git a/e b/e + --- a/e + +++ b/e + @@ -1,1 +1,1 @@ + -123 + +321 + $ hg commit -m 'ambiguity from size' + + $ cat e + 321 + $ touch -t 200001010000 e + $ hg debugrebuildstate + + $ cat >> .hg/hgrc < [fakedirstatewritetime] + > # emulate invoking dirstate.write() via repo.status() + > # at 2000-01-01 00:00 + > fakenow = 200001010000 + > + > [extensions] + > fakedirstatewritetime = $TESTDIR/fakedirstatewritetime.py + > EOF + $ hg revert -r 0 e + $ cat >> .hg/hgrc < [extensions] + > fakedirstatewritetime = ! + > EOF + + $ cat e + 123 + $ touch -t 200001010000 e + $ hg status -A e + M e + $ cd .. diff --git a/tests/test-subrepo.t b/tests/test-subrepo.t --- a/tests/test-subrepo.t +++ b/tests/test-subrepo.t @@ -939,14 +939,32 @@ Issue1977: multirepo push should fail if test if untracked file is not overwritten +(this also tests that updated .hgsubstate is treated as "modified", +when 'merge.update()' is aborted before 'merge.recordupdates()', even +if none of mode, size and timestamp of it isn't changed on the +filesystem (see also issue4583)) + $ echo issue3276_ok > repo/s/b $ hg -R repo2 push -f -q $ touch -t 200001010000 repo/.hgsubstate - $ hg -R repo status --config debug.dirstate.delaywrite=2 repo/.hgsubstate + + $ cat >> repo/.hg/hgrc < [fakedirstatewritetime] + > # emulate invoking dirstate.write() via repo.status() + > # at 2000-01-01 00:00 + > fakenow = 200001010000 + > + > [extensions] + > fakedirstatewritetime = $TESTDIR/fakedirstatewritetime.py + > EOF $ hg -R repo update b: untracked file differs abort: untracked files in working directory differ from files in requested revision (in subrepo s) [255] + $ cat >> repo/.hg/hgrc < [extensions] + > fakedirstatewritetime = ! + > EOF $ cat repo/s/b issue3276_ok