merge.graft: add option to keep second parent
authorAndrew Halberstadt <ahalberstadt@mozilla.com>
Thu, 03 Dec 2015 23:01:59 -0500
changeset 27267 d6859d86a5d5
parent 27266 4dccc37b87bd
child 27268 ed1660ce99d9
merge.graft: add option to keep second parent Currently merge.graft re-writes the dirstate so only a single parent is kept. For some cases, like evolving a merge commit, this behaviour is not desired. More specifically, this is needed to fix issue4389.
mercurial/merge.py
--- a/mercurial/merge.py	Sat Dec 05 21:11:04 2015 -0800
+++ b/mercurial/merge.py	Thu Dec 03 23:01:59 2015 -0500
@@ -1489,18 +1489,19 @@
         repo.hook('update', parent1=xp1, parent2=xp2, error=stats[3])
     return stats
 
-def graft(repo, ctx, pctx, labels):
+def graft(repo, ctx, pctx, labels, keepparent=False):
     """Do a graft-like merge.
 
     This is a merge where the merge ancestor is chosen such that one
     or more changesets are grafted onto the current changeset. In
     addition to the merge, this fixes up the dirstate to include only
-    a single parent and tries to duplicate any renames/copies
-    appropriately.
+    a single parent (if keepparent is False) and tries to duplicate any
+    renames/copies appropriately.
 
     ctx - changeset to rebase
     pctx - merge base, usually ctx.p1()
     labels - merge labels eg ['local', 'graft']
+    keepparent - keep second parent if any
 
     """
     # If we're grafting a descendant onto an ancestor, be sure to pass
@@ -1514,9 +1515,14 @@
     stats = update(repo, ctx.node(), True, True, False, pctx.node(),
                    mergeancestor=mergeancestor, labels=labels)
 
-    # drop the second merge parent
+    pother = nullid
+    parents = ctx.parents()
+    if keepparent and len(parents) == 2 and pctx in parents:
+        parents.remove(pctx)
+        pother = parents[0].node()
+
     repo.dirstate.beginparentchange()
-    repo.setparents(repo['.'].node(), nullid)
+    repo.setparents(repo['.'].node(), pother)
     repo.dirstate.write(repo.currenttransaction())
     # fix up dirstate for copies and renames
     copies.duplicatecopies(repo, ctx.rev(), pctx.rev())