[PATCH evolve-ext] evolve: handle merge commit with single obsolete parent (issue4389)
Andrew Halberstadt
halbersa at gmail.com
Fri Dec 18 08:38:57 CST 2015
# HG changeset patch
# User Andrew Halberstadt <ahalberstadt at mozilla.com>
# Date 1448588311 18000
# Thu Nov 26 20:38:31 2015 -0500
# Node ID 414873a5d2457722b2d473b62136b8f8eb01b0c9
# Parent 52c276d2ddb2f076c84ef8258038ef7b5ee00fe4
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 --git a/hgext/evolve.py b/hgext/evolve.py
--- a/hgext/evolve.py
+++ b/hgext/evolve.py
@@ -891,30 +891,32 @@ def rewrite(repo, old, updates, head, ne
tr.close()
return newid, created
finally:
lockmod.release(tr, lock, wlock)
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'),
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 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()
commitmsg = orig.description()
cache = {}
sha1s = re.findall(sha1re, commitmsg)
unfi = repo.unfiltered()
@@ -944,17 +946,29 @@ 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'])
+
+ 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)')
nodenew = _relocatecommit(repo, orig, commitmsg)
except error.Abort as exc:
repo.dirstate.beginparentchange()
repo.setparents(repo['.'].node(), nullid)
writedirstate(repo.dirstate, tr)
@@ -1728,23 +1742,30 @@ def _aspiringdescendant(repo, revs):
if unstable not in result:
tovisit.append(unstable)
result.add(unstable)
return sorted(result - target)
def _solveunstable(ui, repo, orig, dryrun=False, confirm=False,
progresscb=None):
"""Stabilize a 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 == [()]:
ui.debug("stabilize target %s is plain dead,"
" trying to stabilize on its parent\n" %
obs)
obs = obs.parents()[0]
newer = obsolete.successorssets(repo, obs.node())
@@ -1780,17 +1801,17 @@ def _solveunstable(ui, repo, orig, dryru
todo = 'hg rebase -r %s -d %s\n' % (orig, target)
if dryrun:
repo.ui.write(todo)
else:
repo.ui.note(todo)
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'))
repo.ui.write_err(
_('fix conflict and run "hg evolve --continue"'
' or use "hg update -C" to abort\n'))
raise
diff --git a/tests/test-unstable.t b/tests/test-unstable.t
--- a/tests/test-unstable.t
+++ b/tests/test-unstable.t
@@ -98,27 +98,23 @@ Not supported yet
| x 1:b3264cec9506 at default(draft) add _a
|/
o 0:b4952fcf48cf at default(draft) add base
$ 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 <old> --succ <new>` to obsolete the old one)
- [255]
+ working directory is now at 0bf3f3a59c8c
$ hg log -G
- @ 4:47127ea62e5f at default(draft) aprime
- |
- | o 3:6b4280e33286 at default(draft) merge
- | |\
- +---o 2:474da87dd33b at default(draft) add _c
+ @ 5:0bf3f3a59c8c at default(draft) merge
+ |\
+ | o 4:47127ea62e5f at default(draft) aprime
| |
- | x 1:b3264cec9506 at default(draft) add _a
+ o | 2:474da87dd33b at default(draft) add _c
|/
o 0:b4952fcf48cf at default(draft) add base
$ cd ..
===============================================================================
Test instability resolution for a merge changeset unstable because both
@@ -153,19 +149,17 @@ Not supported yet
+---x 2:474da87dd33b at default(draft) add _c
| |
| x 1:b3264cec9506 at default(draft) add _a
|/
o 0:b4952fcf48cf at default(draft) add base
$ 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 <old> --succ <new>` to obsolete the old one)
[255]
$ hg log -G
@ 5:2db39fda7e2f at default(draft) cprime
|
| o 4:47127ea62e5f at default(draft) aprime
|/
| o 3:6b4280e33286 at default(draft) merge
More information about the Mercurial-devel
mailing list