Patchwork [9,of,9,V2] localrepo: write recent dirstate out for external process (BC) (issue4378)

mail settings
Submitter Katsunori FUJIWARA
Date May 2, 2015, 3:59 p.m.
Message ID <5ef7b9bc8054575a8549.1430582384@feefifofum>
Download mbox | patch
Permalink /patch/8861/
State Superseded
Headers show


Katsunori FUJIWARA - May 2, 2015, 3:59 p.m.
# HG changeset patch
# User FUJIWARA Katsunori <>
# Date 1430582197 -32400
#      Sun May 03 00:56:37 2015 +0900
# Node ID 5ef7b9bc8054575a8549704422e0720823e113cf
# Parent  2ff6031e1e5737e8c36e6862a0b3898a5cec9091
localrepo: write recent dirstate out for external process (BC) (issue4378)

Before this patch, "localrepository.commit()" invokes external
processes below without writing recent dirstate out ("commit" hooks
are invoked after writing dirstate out by "wlock.release()")

  - editor for the commit log
  - "precommit" hooks
  - "pretxncommit" hooks

This causes unexpected output of Mercurial commands referring dirstate
in external processes.

In the issue4378 case, old parent revision is already stripped, and
parents of dirstate are changed in memory. But ".hg/dirstate" is not
yet updated at editor invocation.

Before 49148d7868df, lack of updating dirstate didn't cause problem,
because editor process was invoked before refreshing (= dirstate was
not yet changed).

On the other hand, after 49148d7868df, editor process is invoked
inside "localrepository.commit()" (= refreshing is already done) and
lack of updating dirstate causes problem.

This patch writes recent dirstate out in "localrepository.commit()"
before invocation of editor for the commit log, "precommit" and
"pretxncommit" hooks.

Before 49148d7868df, "hg diff" in external editor process shows
"changes newly imported into the topmost patch". But after this patch,
it shows "all changes recorded in the topmost patch after refreshing"
(= "hg qdiff" in previous case).

The latter behavior looks reasonable, because "hg diff" in editor
process consistently shows "what changes new revision records"
regardless of commands invoking editor process, even though backward
compatibility may be broken.

"test-mq-qrefresh-replace-log-message.t" examines that the parent of
the working directory is not the refreshed revision but the parent of
it: updated parent information can ensure that changed dirstate is
also written out.


diff --git a/mercurial/ b/mercurial/
--- a/mercurial/
+++ b/mercurial/
@@ -1480,6 +1480,8 @@ 
                     raise util.Abort(_('unresolved merge conflicts '
                                        '(see "hg help resolve")'))
+            self.dirstate.write() # for external editor and hooks
             if editor:
                 cctx._text = editor(self, cctx, subs)
             edited = (text != cctx._text)
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
@@ -999,10 +999,6 @@ 
   > 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'
@@ -1017,7 +1013,7 @@ 
   $ hg -R no-largefiles -q pull --rebase
   Invoking status precommit hook
-  M normal3
+  A normal3
 (test reverting)
diff --git a/tests/test-mq-qrefresh-replace-log-message.t b/tests/test-mq-qrefresh-replace-log-message.t
--- a/tests/test-mq-qrefresh-replace-log-message.t
+++ b/tests/test-mq-qrefresh-replace-log-message.t
@@ -101,6 +101,7 @@ 
 Test saving last-message.txt:
   $ cat > $TESTTMP/ << EOF
+  > hg parents --template "{rev}\n"
   > echo "==== before editing"
   > cat \$1
   > echo "===="
@@ -165,7 +166,10 @@ 
   $ rm -f .hg/last-message.txt
   $ hg status --rev "second-patch^1" -arm
   A file2
+  $ hg log -r "." --template "{rev}\n"
+  1
   $ HGEDITOR="sh $TESTTMP/" hg qrefresh -e
+  0
   ==== before editing
   Fifth commit message
    This is the 5th log message