Patchwork [3,of,9,STABLE] graft: keep the result of merging even after abort of commit

login
register
mail settings
Submitter Katsunori FUJIWARA
Date Oct. 1, 2014, 4:18 p.m.
Message ID <4bd28b652e70c69916dc.1412180310@feefifofum>
Download mbox | patch
Permalink /patch/6061/
State Changes Requested
Headers show

Comments

Katsunori FUJIWARA - Oct. 1, 2014, 4:18 p.m.
# HG changeset patch
# User FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
# Date 1412179386 -32400
#      Thu Oct 02 01:03:06 2014 +0900
# Branch stable
# Node ID 4bd28b652e70c69916dc1db74a77175eb97f8670
# Parent  cd19d1707e37b038755dd5cf38a8d02494ea3434
graft: keep the result of merging even after abort of commit

Before this patch, the 2nd parent of merging is dropped by
"localrepository.setparents()", when commit is aborted (e.g. failure
by "hg graft --continue" with files not yet marked as resolved).

This dropping prevents users from re-merging by "hg resolve".

This patch keeps the result of merging, even after abort of commit, by:

  - "dirstate.write()" to save the result of merging
  - "dirstateguard" to restore dirstate at failure

This patch puts "dirstate.write()" invocation after checking
unresolved conflicts, because dirty dirstate is written out also by
"wlock.release", when the exception is raised.

This "dirstate.write()" invocation will be meaningless in the future,
because it will be invoked also in "merge.update()" to fix the issue
that recent dirstate isn't visible to external "preupdate"/"update"
hooks.

Patch

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -3259,18 +3259,28 @@ 
                     raise util.Abort(
                         _("unresolved conflicts, can't continue"),
                         hint=_('use hg resolve and hg graft --continue'))
+
+                # write dirstate explicitly to keep the result of merging
+                # even after unexpected abort of commit
+                repo.dirstate.write()
             else:
                 cont = False
 
-            # drop the second merge parent
-            repo.setparents(current.node(), nullid)
-            repo.dirstate.write()
-            # fix up dirstate for copies and renames
-            cmdutil.duplicatecopies(repo, ctx.rev(), ctx.p1().rev())
-
-            # commit
-            node = repo.commit(text=message, user=user,
-                        date=date, extra=extra, editor=editor)
+            dsguard = cmdutil.dirstateguard(repo, 'graft')
+            try:
+                # drop the second merge parent
+                repo.setparents(current.node(), nullid)
+                repo.dirstate.write()
+                # fix up dirstate for copies and renames
+                cmdutil.duplicatecopies(repo, ctx.rev(), ctx.p1().rev())
+
+                # commit
+                node = repo.commit(text=message, user=user,
+                                   date=date, extra=extra, editor=editor)
+                dsguard.close()
+            finally:
+                dsguard.release()
+
             if node is None:
                 ui.status(_('graft for revision %s is empty\n') % ctx.rev())
             else:
diff --git a/tests/test-graft.t b/tests/test-graft.t
--- a/tests/test-graft.t
+++ b/tests/test-graft.t
@@ -223,13 +223,20 @@ 
   abort: unresolved conflicts, can't continue
   (use hg resolve and hg graft --continue)
   [255]
+  $ hg parents --template "{node|short}\n"
+  1905859650ec
+  9c233e8e184d
 
 Continue without resolve should fail:
+(also check keeping the 2nd parent of merging)
 
   $ hg graft -c
   grafting revision 4
   abort: unresolved merge conflicts (see hg help resolve)
   [255]
+  $ hg parents --template "{node|short}\n"
+  1905859650ec
+  9c233e8e184d
 
 Fix up:
 
@@ -247,6 +254,27 @@ 
   abort: can't specify --continue and revisions
   [255]
 
+Failure of continue should keep the 2nd parent of merging:
+(case of the failure for prtxncommit hook)
+
+  $ cat >> .hg/hgrc <<EOF
+  > [hooks]
+  > pretxncommit.forceabort = false
+  > EOF
+  $ hg graft -c
+  grafting revision 4
+  transaction abort!
+  rollback completed
+  abort: pretxncommit.forceabort hook exited with status 1
+  [255]
+  $ hg parents --template "{node|short}\n"
+  1905859650ec
+  9c233e8e184d
+  $ cat >> .hg/hgrc <<EOF
+  > [hooks]
+  > pretxncommit.forceabort =
+  > EOF
+
 Continue for real, clobber usernames
 
   $ hg graft -c -U