# HG changeset patch # User Andrew Halberstadt # Date 1448588311 18000 # Node ID 526253198860fdbdcae01380ae97727195039f44 # Parent 0c8548df67feb1cd33b274b999e14a91864816de evolve: handle merge commit with single obsolete parent (issue4389) This handles evolving merge commits with a single obsolete parent. Merge commits with two obsolete parents are still unsupported. Note this depends on a change to merge.graft in core. Older versions of mercurial will not have this functionality. Also, test-unstable.t will fail with older versions. diff -r 0c8548df67fe -r 526253198860 README --- a/README Tue Dec 22 14:11:09 2015 +0000 +++ b/README Thu Nov 26 20:38:31 2015 -0500 @@ -62,6 +62,7 @@ - tests: drop our copy of 'run-tests.py' use core one instead, - bookmark: do all bookmark movement within a transaction. - evolve: compatibility with Mercurial 3.7 +- evolve: support merge with a single obsolete parent. 5.2.2 -- diff -r 0c8548df67fe -r 526253198860 hgext/evolve.py --- 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 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 --succ ` " - "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 --succ " + "` 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 " + "--succ ` 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')) diff -r 0c8548df67fe -r 526253198860 tests/test-unstable.t --- a/tests/test-unstable.t Tue Dec 22 14:11:09 2015 +0000 +++ b/tests/test-unstable.t Thu Nov 26 20:38:31 2015 -0500 @@ -103,17 +103,13 @@ $ hg evo --all --any --unstable move:[3] merge atop:[4] aprime - abort: no support for evolving merge changesets yet - (Redo the merge and use `hg prune --succ ` to obsolete the old one) - [255] + working directory is now at 0bf3f3a59c8c $ hg log -G - @ 4:47127ea62e5f@default(draft) aprime - | - | o 3:6b4280e33286@default(draft) merge - | |\ - +---o 2:474da87dd33b@default(draft) add _c + @ 5:0bf3f3a59c8c@default(draft) merge + |\ + | o 4:47127ea62e5f@default(draft) aprime | | - | x 1:b3264cec9506@default(draft) add _a + o | 2:474da87dd33b@default(draft) add _c |/ o 0:b4952fcf48cf@default(draft) add base @@ -158,9 +154,7 @@ $ hg evo --all --any --unstable - move:[3] merge - atop:[5] cprime - abort: no support for evolving merge changesets yet + abort: no support for evolving merge changesets with two obsolete parents yet (Redo the merge and use `hg prune --succ ` to obsolete the old one) [255] $ hg log -G