Bug 3498 - graft: cannot redo 3-way merge by "hg resolve" if graft interrupted
Summary: graft: cannot redo 3-way merge by "hg resolve" if graft interrupted
Status: RESOLVED FIXED
Alias: None
Product: Mercurial
Classification: Unclassified
Component: Mercurial (show other bugs)
Version: unspecified
Hardware: All All
: normal bug
Assignee: Bugzilla
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-06-14 11:59 UTC by Yuya Nishihara
Modified: 2012-07-02 08:25 UTC (History)
3 users (show)

See Also:
Python Version: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Yuya Nishihara 2012-06-14 11:59 UTC
If "hg graft" fails with conflicts, it says "use hg resolve":

% hg graft 3 --tool internal:merge 
grafting revision 3
merging foo
warning: conflicts during merge.
merging foo incomplete! (edit conflicts, then use 'hg resolve --mark')
abort: unresolved conflicts, can't continue
(use hg resolve and hg graft --continue)

but in such case, the working directory does not have two parents,
so "hg resolve" does nothing:

% hg resolve --all

% hg resolve -l
U foo

only "hg resolve -m" works.


I guess "resolve" need to handle graft failure differently than merge's,
because graft needs to trick common ancestor:

http://selenic.com/repo/hg/file/2255950e1f76/mercurial/commands.py#l2744
Comment 1 Matt Mackall 2012-06-15 07:36 UTC
It's probably due to the location of this call to setparents:

 http://www.selenic.com/hg/file/622aa57a90b1/mercurial/commands.py#l2752

By comparison, rebase does setparents after checking the merge stats:

 http://www.selenic.com/hg/file/622aa57a90b1/hgext/rebase.py#l270
Comment 2 Yuya Nishihara 2012-06-15 10:15 UTC
You're right. The following change seems to solve the problem.
I'll test it and send patch to mercurial-devel.

--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -2748,11 +2748,6 @@ def graft(ui, repo, *revs, **opts):
                                             ctx.p1().node())
                 finally:
                     repo.ui.setconfig('ui', 'forcemerge', '')
-                # 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())
                 # report any conflicts
                 if stats and stats[3] > 0:
                     # write out state for --continue
@@ -2764,6 +2759,12 @@ def graft(ui, repo, *revs, **opts):
             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
             source = ctx.extra().get('source')
             if not source:
Comment 3 Yuya Nishihara 2012-07-02 08:25 UTC
Fixed by 52ea9ce5b641.