diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -1184,9 +1184,17 @@ def graft(repo, ctx, pctx, labels): labels - merge labels eg ['local', 'graft'] """ + # If we're grafting a descendant onto an ancestor, be sure to pass + # mergeancestor=True to update. This does two things: 1) allows the merge if + # the destination is the same as the parent of the ctx (so we can use graft + # to copy commits), and 2) informs update that the incoming changes are + # newer than the destination so it doesn't prompt about "remote changed foo + # which local deleted". + mergeancestor = repo.changelog.isancestor(repo['.'].node(), ctx.node()) stats = update(repo, ctx.node(), True, True, False, pctx.node(), - labels=labels) + mergeancestor=mergeancestor, labels=labels) + # drop the second merge parent repo.dirstate.beginparentchange() repo.setparents(repo['.'].node(), nullid) diff --git a/tests/test-graft.t b/tests/test-graft.t --- a/tests/test-graft.t +++ b/tests/test-graft.t @@ -730,3 +730,29 @@ Empty graft $ hg graft -f 27 grafting 27:3d35c4c79e5a "28" note: graft of 27:3d35c4c79e5a created no changes to commit + + $ cd .. + +Graft to duplicate a commit + + $ hg init graftsibling + $ cd graftsibling + $ touch a + $ hg commit -qAm a + $ touch b + $ hg commit -qAm b + $ hg log -G -T '{rev}\n' + @ 1 + | + o 0 + + $ hg up -q 0 + $ hg graft -r 1 + grafting 1:0e067c57feba "b" (tip) + $ hg log -G -T '{rev}\n' + @ 2 + | + | o 1 + |/ + o 0 + diff --git a/tests/test-histedit-non-commute-abort.t b/tests/test-histedit-non-commute-abort.t --- a/tests/test-histedit-non-commute-abort.t +++ b/tests/test-histedit-non-commute-abort.t @@ -70,8 +70,6 @@ edit the history > pick 652413bf663e f > EOF 0 files updated, 0 files merged, 2 files removed, 0 files unresolved - remote changed e which local deleted - use (c)hanged version or leave (d)eleted? c 0 files updated, 0 files merged, 0 files removed, 0 files unresolved merging e warning: conflicts during merge.