diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -790,7 +790,8 @@ cmdutil.checkunfinished(repo) cmdutil.bailifchanged(repo) - node = scmutil.revsingle(repo, rev).node() + ctx = scmutil.revsingle(repo, rev) + node = ctx.node() op1, op2 = repo.dirstate.parents() if not repo.changelog.isancestor(node, op1): @@ -821,14 +822,7 @@ with dirstateguard.dirstateguard(repo, b'backout'): overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')} with ui.configoverride(overrides, b'backout'): - stats = mergemod.update( - repo, - parent, - branchmerge=True, - force=True, - ancestor=node, - mergeancestor=False, - ) + stats = mergemod.back_out(ctx, parent=repo[parent]) repo.setparents(op1, op2) hg._showstats(repo, stats) if stats.unresolvedcount: diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -2236,6 +2236,23 @@ return stats +def back_out(ctx, parent=None, wc=None): + if parent is None: + if ctx.p2() is not None: + raise error.ProgrammingError( + b"must specify parent of merge commit to back out" + ) + parent = ctx.p1() + return update( + ctx.repo(), + parent, + branchmerge=True, + force=True, + ancestor=ctx.node(), + mergeancestor=False, + ) + + def purge( repo, matcher,