evolve: stabilize now handle conflicting changeset
Some a lot of rough edge but it just damn work.
--- a/hgext/evolve.py Thu Aug 23 14:15:36 2012 +0200
+++ b/hgext/evolve.py Thu Aug 23 17:40:28 2012 +0200
@@ -22,6 +22,7 @@
from mercurial import context
from mercurial import copies
from mercurial import util
+from mercurial import merge
from mercurial.i18n import _
from mercurial.commands import walkopts, commitopts, commitopts2
from mercurial import hg
@@ -264,14 +265,14 @@
else:
ui.write_err(_('no troubled changeset\n'))
return 1
+ cmdutil.bailifchanged(repo)
troubles = tr.troubles()
if 'unstable' in troubles:
return _solveunstable(ui, repo, tr, opts['dry_run'])
elif 'latecomer' in troubles:
return _solvelatecomer(ui, repo, tr, opts['dry_run'])
elif 'conflicting' in troubles:
- ui.write_err(_('conflicting not handled yet\n'))
- return 4
+ return _solveconflicting(ui, repo, tr, opts['dry_run'])
else:
assert False # WHAT? unknown troubles
@@ -444,6 +445,99 @@
finally:
wlock.release()
+def _solveconflicting(ui, repo, conflicting, dryrun=False):
+ obsolete = extensions.find('obsolete')
+ base, others = conflictingdata(conflicting)
+ if len(others) > 1:
+ raise util.Abort("We do not handle split yet")
+ other = others[0]
+ if conflicting.phase() <= phases.public:
+ raise util.Abort("We can't resolve this conflict from the public side")
+ if len(other.parents()) > 1:
+ raise util.Abort("conflicting changeset can't be a merge (yet)")
+ if other.p1() not in conflicting.parents():
+ raise util.Abort("parent are not common (not handled yet)")
+
+ displayer = cmdutil.show_changeset(ui, repo, {'template': shorttemplate})
+ ui.status(_('merge:'))
+ if not ui.quiet:
+ displayer.show(conflicting)
+ ui.status(_('with: '))
+ if not ui.quiet:
+ displayer.show(other)
+ ui.status(_('base: '))
+ if not ui.quiet:
+ displayer.show(base)
+ if dryrun:
+ ui.write('hg update -c %s &&\n' % conflicting)
+ ui.write('hg merge %s && \n' % other)
+ ui.write('hg commit -m "auto merge resolving conflict between %s and %s"&&\n'
+ % (conflicting, other))
+ ui.write('hg up -C %s &&\n' % base)
+ ui.write('hg revert --all --rev tip &&\n')
+ ui.write('hg commit -m "`hg log -r %s --template={desc}`";\n' % conflicting)
+ return
+ #oldphase = max(conflicting.phase(), other.phase())
+ wlock = repo.wlock()
+ try:
+ lock = repo.lock()
+ try:
+ if conflicting not in repo[None].parents():
+ repo.ui.status(_('updating to "local" conflict\n'))
+ hg.update(repo, conflicting.rev())
+ repo.ui.note(_('merging conflicting changeset\n'))
+ stats = merge.update(repo,
+ other.node(),
+ branchmerge=True,
+ force=False,
+ partial=None,
+ ancestor=base.node(),
+ mergeancestor=True)
+ hg._showstats(repo, stats)
+ if stats[3]:
+ repo.ui.status(_("use 'hg resolve' to retry unresolved file merges "
+ "or 'hg update -C .' to abandon\n"))
+ #repo.dirstate.write()
+ if stats[3] > 0:
+ raise util.Abort('GASP! Merge Conflict! You are on you own chap!')
+ tr = repo.transaction('stabilize-conflicting')
+ try:
+ repo.dirstate.setparents(conflicting.node(), node.nullid)
+ oldlen = len(repo)
+ amend(ui, repo)
+ if oldlen == len(repo):
+ new = conflicting
+ # no changes
+ else:
+ new = repo['.']
+ obsolete.createmarkers(repo, [(other, (new,))])
+ phases.retractboundary(repo, other.phase(), [new.node()])
+ tr.close()
+ finally:
+ tr.release()
+ finally:
+ lock.release()
+ finally:
+ wlock.release()
+
+
+def conflictingdata(ctx):
+ """return base, other part of a conflict
+
+ This only return the first one.
+
+ XXX this woobly function won't survive XXX
+ """
+ obsolete = extensions.find('obsolete')
+ for base in ctx._repo.set('reverse(precursors(%d))', ctx):
+ newer = obsolete.newerversion(ctx._repo, base.node())
+ # drop filter and solution including the original ctx
+ newer = [n for n in newer if n and ctx.node() not in n]
+ if newer:
+ return base, tuple(ctx._repo[o] for o in newer[0])
+ raise KeyError('Base seem unknown. This case is not handled yet.')
+
+
shorttemplate = '[{rev}] {desc|firstline}\n'
--- a/tests/test-stabilize-result.t Thu Aug 23 14:15:36 2012 +0200
+++ b/tests/test-stabilize-result.t Thu Aug 23 17:40:28 2012 +0200
@@ -175,15 +175,27 @@
Stabilize of conflicting changeset with same parent
====================================================
-
+ $ rm a.orig
$ hg up 9
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ cat << EOF >> a
+ > flore
+ > arthur
+ > zephir
+ > some
+ > less
+ > conflict
+ > EOF
+ $ hg ci -m 'More addition'
+ created new head
$ glog
- o 14:1d94fef80e85@default(draft) bk:[] latecomer update to e3183e9c0961:
+ @ 15:7391601a4bfa@default(draft) bk:[] More addition
|
- | @ 9:355c5cda4de1@default(draft) bk:[] add c
+ | o 14:1d94fef80e85@default(draft) bk:[] latecomer update to e3183e9c0961:
| |
- o | 8:e3183e9c0961@default(public) bk:[] newer a
+ o | 9:355c5cda4de1@default(draft) bk:[] add c
+ | |
+ | o 8:e3183e9c0961@default(public) bk:[] newer a
|/
o 7:e8cc1b534401@default(public) bk:[changea] changea
|
@@ -191,7 +203,7 @@
$ echo 'babar' >> a
$ hg amend
- $ hg up 9
+ $ hg up 15
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
Working directory parent is obsolete
$ mv a a.old
@@ -201,12 +213,14 @@
$ hg amend
2 new conflictings changesets
$ glog
- @ 18:5d568f72d576@default(draft) bk:[] add c
+ @ 19:3883461cc228@default(draft) bk:[] More addition
|
- | o 16:a311193de6c8@default(draft) bk:[] add c
+ | o 17:4754d61bc2db@default(draft) bk:[] More addition
|/
| o 14:1d94fef80e85@default(draft) bk:[] latecomer update to e3183e9c0961:
| |
+ o | 9:355c5cda4de1@default(draft) bk:[] add c
+ | |
| o 8:e3183e9c0961@default(public) bk:[] newer a
|/
o 7:e8cc1b534401@default(public) bk:[changea] changea
@@ -216,6 +230,62 @@
Stabilize It
- $ hg stabilize
- conflicting not handled yet
- [4]
+ $ hg stabilize -qn
+ hg update -c 3883461cc228 &&
+ hg merge 4754d61bc2db &&
+ hg commit -m "auto merge resolving conflict between 3883461cc228 and 4754d61bc2db"&&
+ hg up -C 7391601a4bfa &&
+ hg revert --all --rev tip &&
+ hg commit -m "`hg log -r 3883461cc228 --template={desc}`";
+ $ hg stabilize -v
+ merge:[19] More addition
+ with: [17] More addition
+ base: [15] More addition
+ merging conflicting changeset
+ resolving manifests
+ merging a
+ 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+ a
+ a
+ $ hg st
+ $ hg amend -d '0 0' -m 'More addition' # kill date variation XXX should be done in stabilize
+ $ glog
+ @ 22:ac6d600735a4@default(draft) bk:[] More addition
+ |
+ | o 14:1d94fef80e85@default(draft) bk:[] latecomer update to e3183e9c0961:
+ | |
+ o | 9:355c5cda4de1@default(draft) bk:[] add c
+ | |
+ | o 8:e3183e9c0961@default(public) bk:[] newer a
+ |/
+ o 7:e8cc1b534401@default(public) bk:[changea] changea
+ |
+ o 0:07f494440405@default(public) bk:[] adda
+
+ $ hg summary
+ parent: 22:ac6d600735a4 tip
+ More addition
+ branch: default
+ commit: (clean)
+ update: 19 new changesets, 14 branch heads (merge)
+ $ hg export .
+ # HG changeset patch
+ # User test
+ # Date 0 0
+ # Node ID ac6d600735a49ee377e29d1f74a0576e8c972e7b
+ # Parent 355c5cda4de162658ed9f961a98a73a10b3167b1
+ More addition
+
+ diff -r 355c5cda4de1 -r ac6d600735a4 a
+ --- a/a Thu Jan 01 00:00:00 1970 +0000
+ +++ b/a Thu Jan 01 00:00:00 1970 +0000
+ @@ -1,1 +1,9 @@
+ +jungle
+ a
+ +flore
+ +arthur
+ +zephir
+ +some
+ +less
+ +conflict
+ +babar