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

login
register
mail settings
Submitter Katsunori FUJIWARA
Date May 7, 2015, 3:15 a.m.
Message ID <624f909ffd661f3524bc.1430968556@feefifofum>
Download mbox | patch
Permalink /patch/8943/
State Accepted
Delegated to: Pierre-Yves David
Headers show

Comments

Katsunori FUJIWARA - May 7, 2015, 3:15 a.m.
# HG changeset patch
# User FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
# Date 1430968031 -32400
#      Thu May 07 12:07:11 2015 +0900
# Node ID 624f909ffd661f3524bc4ba62d43e527229be5ea
# Parent  400adce7961fad91078ba6be48fd6e405c843733
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.
Pierre-Yves David - May 12, 2015, 1:39 a.m.
On 05/06/2015 08:15 PM, FUJIWARA Katsunori wrote:
> # HG changeset patch
> # User FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
> # Date 1430968031 -32400
> #      Thu May 07 12:07:11 2015 +0900
> # Node ID 624f909ffd661f3524bc4ba62d43e527229be5ea
> # Parent  400adce7961fad91078ba6be48fd6e405c843733
> localrepo: write recent dirstate out for external process (BC) (issue4378)

These are pushed to the clowncopter after fixes to the first one and 
review of the commit message by Durham and I.

Patch

diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1476,6 +1476,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/editor.sh << 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/editor.sh" hg qrefresh -e
+  0
   ==== before editing
   Fifth commit message
    This is the 5th log message