[PATCH evolve-ext] evolve: handle merge commit with single obsolete parent (issue4389)
Pierre-Yves David
pierre-yves.david at ens-lyon.org
Wed Dec 2 19:58:37 UTC 2015
On 11/26/2015 06:41 PM, Andrew Halberstadt wrote:
> # HG changeset patch
> # User Andrew Halberstadt <ahalberstadt at mozilla.com>
> # Date 1448588311 18000
> # Thu Nov 26 20:38:31 2015 -0500
> # Node ID 21b5e4b3df092855c554331587fdd7b713b9551e
> # Parent 72f50a17780674de8f372803a333d43c77230df5
> evolve: handle merge commit with single obsolete parent (issue4389)
This is a nice change, but it is done in the wrong layer.
The relocate function is not expected to know anything about the higher
level evolution process. We should not be adding evolution related logic
as this patch do.
The code modified here is responsible for finding the proper merge base
and bail out in case of merge because of the ambiguity. We should add
some "parents/base" argument and compute what it should be in the higher
function actually calling relocate.
> diff --git a/hgext/evolve.py b/hgext/evolve.py
> --- a/hgext/evolve.py
> +++ b/hgext/evolve.py
> @@ -899,20 +899,32 @@ def relocate(repo, orig, dest, keepbranc
> """rewrite <rev> on dest"""
> if orig.rev() == dest.rev():
> raise util.Abort(_('tried to relocate a node on top of itself'),
> hint=_("This shouldn't happen. If you still "
> "need to move changesets, please do so "
> "manually with nothing to rebase - working "
> "directory parent is also destination"))
>
> - if not orig.p2().rev() == node.nullrev:
> - raise util.Abort(
> - 'no support for evolving merge changesets yet',
> - hint="Redo the merge and use `hg prune <old> --succ <new>` to obsolete the old one")
> + parents = orig.parents()
> + if len(parents) == 2:
> + if all(p.obsolete() for p in parents):
> + raise util.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")
> +
> + for p in parents:
> + if p.obsolete():
> + pctx = p
> + else:
> + pother = p.node()
> + else:
> + pctx = orig.p1()
> + pother = nullid
> +
> destbookmarks = repo.nodebookmarks(dest.node())
> nodesrc = orig.node()
> destphase = repo[nodesrc].phase()
> commitmsg = orig.description()
>
> cache = {}
> sha1s = re.findall(sha1re, commitmsg)
> unfi = repo.unfiltered()
> @@ -942,17 +954,26 @@ def relocate(repo, orig, dest, keepbranc
> try:
> if repo['.'].rev() != dest.rev():
> merge.update(repo, dest, False, True, False)
> if bmactive(repo):
> repo.ui.status(_("(leaving bookmark %s)\n") % bmactive(repo))
> bmdeactivate(repo)
> if keepbranch:
> repo.dirstate.setbranch(orig.branch())
> - r = merge.graft(repo, orig, orig.p1(), ['local', 'graft'])
> + r = merge.graft(repo, orig, pctx, ['local', 'graft'])
> +
> + if pother != nullid:
> + # Add back the original second parent which got nullified
> + # by merge.graft().
> + repo.dirstate.beginparentchange()
> + repo.setparents(repo['.'].node(), pother)
> + repo.dirstate.write(repo.currenttransaction())
> + repo.dirstate.endparentchange()
Could we get hg graft able to grat merge instead (basically the same
drill as what is needed of relocate)
Many thanks for working on this.
--
Pierre-Yves David
More information about the Mercurial-devel
mailing list