hgext/evolve.py
changeset 1576 526253198860
parent 1575 0c8548df67fe
child 1580 b915e0d54db0
--- a/hgext/evolve.py	Tue Dec 22 14:11:09 2015 +0000
+++ b/hgext/evolve.py	Thu Nov 26 20:38:31 2015 -0500
@@ -896,7 +896,7 @@
 class MergeFailure(error.Abort):
     pass
 
-def relocate(repo, orig, dest, keepbranch=False):
+def relocate(repo, orig, dest, pctx=None, keepbranch=False):
     """rewrite <rev> on dest"""
     if orig.rev() == dest.rev():
         raise error.Abort(_('tried to relocate a node on top of itself'),
@@ -905,11 +905,13 @@
                                 "manually with nothing to rebase - working "
                                 "directory parent is also destination"))
 
-    if not orig.p2().rev() == node.nullrev:
-        raise error.Abort(
-            'no support for evolving merge changesets yet',
-            hint="Redo the merge and use `hg prune <old> --succ <new>` "
-                 "to obsolete the old one")
+    if pctx is None:
+        if len(orig.parents()) == 2:
+            raise error.Abort(_("tried to relocate a merge commit without "
+                                "specifying which parent should be moved"),
+                              hint=_("Specify the parent by passing in pctx"))
+        pctx = orig.p1()
+
     destbookmarks = repo.nodebookmarks(dest.node())
     nodesrc = orig.node()
     destphase = repo[nodesrc].phase()
@@ -949,7 +951,19 @@
             bmdeactivate(repo)
             if keepbranch:
                 repo.dirstate.setbranch(orig.branch())
-            r = merge.graft(repo, orig, orig.p1(), ['local', 'graft'])
+
+            try:
+                r = merge.graft(repo, orig, pctx, ['local', 'graft'], True)
+            except TypeError:
+                # not using recent enough mercurial
+                if len(orig.parents()) == 2:
+                    raise error.Abort(
+                        _("no support for evolving merge changesets yet"),
+                        hint=_("Redo the merge and use `hg prune <old> --succ "
+                               "<new>` to obsolete the old one"))
+
+                r = merge.graft(repo, orig, pctx, ['local', 'graft'])
+
             if r[-1]:  #some conflict
                 raise error.Abort(
                         'unresolved merge conflicts (see hg help resolve)')
@@ -1734,13 +1748,20 @@
 def _solveunstable(ui, repo, orig, dryrun=False, confirm=False,
                    progresscb=None):
     """Stabilize an unstable changeset"""
-    obs = orig.parents()[0]
-    if not obs.obsolete() and len(orig.parents()) == 2:
-        obs = orig.parents()[1] # second parent is obsolete ?
-
-    if not obs.obsolete():
+    pctx = orig.p1()
+    if len(orig.parents()) == 2:
+        if not pctx.obsolete():
+            pctx = orig.p2()  # second parent is obsolete ?
+        elif orig.p2().obsolete():
+            raise error.Abort(_("no support for evolving merge changesets "
+                                "with two obsolete parents yet"),
+                              hint=_("Redo the merge and use `hg prune <old> "
+                                   "--succ <new>` to obsolete the old one"))
+
+    if not pctx.obsolete():
         ui.warn(_("cannot solve instability of %s, skipping\n") % orig)
         return False
+    obs = pctx
     newer = obsolete.successorssets(repo, obs.node())
     # search of a parent which is not killed
     while not newer or newer == [()]:
@@ -1786,7 +1807,7 @@
         if progresscb: progresscb()
         keepbranch = orig.p1().branch() != orig.branch()
         try:
-            relocate(repo, orig, target, keepbranch)
+            relocate(repo, orig, target, pctx, keepbranch)
         except MergeFailure:
             repo.opener.write('graftstate', orig.hex() + '\n')
             repo.ui.write_err(_('evolve failed!\n'))