[PATCH evolve-ext] evolve: support hg continue and hg abort
Luke Granger-Brown
lukegb at lukegb.com
Sun Mar 13 19:12:57 UTC 2022
# HG changeset patch
# User Luke Granger-Brown <hg at lukegb.com>
# Date 1647196527 0
# Sun Mar 13 18:35:27 2022 +0000
# Node ID f1d7992cefc201ed029723b1666328d77ff7000e
# Parent 9e0aa8929206db3080cc434089978384077c03fe
evolve: support hg continue and hg abort
`hg evolve` and `hg pick` both already support `hg abort`, but neither of them
support `hg continue`, and `hg fixup` supports neither `hg continue` nor `hg
abort`.
To make the UX a little more consistent with Mercurial core, add support for
continue and abort to all three commands.
diff --git a/hgext3rd/evolve/__init__.py b/hgext3rd/evolve/__init__.py
--- a/hgext3rd/evolve/__init__.py
+++ b/hgext3rd/evolve/__init__.py
@@ -1167,13 +1167,17 @@ def setupevolveunfinished(ui):
statemod.addunfinished(b'evolve', fname=b'evolvestate',
continueflag=True, stopflag=True,
statushint=_msg,
- abortfunc=evolvecmd.hgabortevolve)
+ abortfunc=evolvecmd.hgabortevolve,
+ continuefunc=evolvecmd.hgcontinueevolve)
statemod.addunfinished(b'pick', fname=b'pickstate', continueflag=True,
- abortfunc=cmdrewrite.hgabortpick)
+ abortfunc=cmdrewrite.hgabortpick,
+ continuefunc=cmdrewrite.hgcontinuepick)
_fixup_msg = _(b'To continue: hg fixup --continue\n'
b'To abort: hg fixup --abort\n')
statemod.addunfinished(b'fixup', fname=b'fixup-state',
- continueflag=True, statushint=_fixup_msg)
+ continueflag=True, statushint=_fixup_msg,
+ abortfunc=cmdrewrite.hgabortfixup,
+ continuefunc=cmdrewrite.hgcontinuefixup)
else:
# hg <= 5.0 (5f2f6912c9e6)
estate = (b'evolvestate', False, False, _(b'evolve in progress'),
diff --git a/hgext3rd/evolve/cmdrewrite.py b/hgext3rd/evolve/cmdrewrite.py
--- a/hgext3rd/evolve/cmdrewrite.py
+++ b/hgext3rd/evolve/cmdrewrite.py
@@ -1403,28 +1403,41 @@ def cmdpick(ui, repo, *revs, **opts):
pickstate.save()
raise error.InterventionRequired(_(b"unresolved merge conflicts"
b" (see hg help resolve)"))
- overrides = {(b'phases', b'new-commit'): origctx.phase()}
- with repo.ui.configoverride(overrides, b'pick'):
- newnode = repo.commit(text=origctx.description(),
- user=origctx.user(),
- date=origctx.date(), extra=origctx.extra())
- repo.dirstate.setbranch(origctx.branch())
+ return _dopick(ui, repo, pickstate, origctx)
+
+def _dopick(ui, repo, pickstate, origctx):
+ """shared logic for performing or continuing a pick"""
+ overrides = {(b'phases', b'new-commit'): origctx.phase()}
+ with repo.ui.configoverride(overrides, b'pick'):
+ newnode = repo.commit(text=origctx.description(),
+ user=origctx.user(),
+ date=origctx.date(), extra=origctx.extra())
+ repo.dirstate.setbranch(origctx.branch())
- if pickstate:
- pickstate.delete()
- if newnode is None:
- replacements = {(origctx.node(),): []}
- else:
- newctx = repo[newnode]
- replacements = {(origctx.node(),): [newctx.node()]}
- compat.cleanupnodes(repo, replacements, operation=b"pick")
+ if pickstate:
+ pickstate.delete()
+ if newnode is None:
+ replacements = {(origctx.node(),): []}
+ else:
+ newctx = repo[newnode]
+ replacements = {(origctx.node(),): [newctx.node()]}
+ compat.cleanupnodes(repo, replacements, operation=b"pick")
- if newnode is None:
- ui.warn(_(b"note: picking %d:%s created no changes to commit\n") %
- (origctx.rev(), origctx))
- return 0
+ if newnode is None:
+ ui.warn(_(b"note: picking %d:%s created no changes to commit\n") %
+ (origctx.rev(), origctx))
+ return 0
+
+ return 0
- return 0
+def hgcontinuepick(ui, repo):
+ """logic to continue pick using 'hg continue'"""
+ with repo.wlock(), repo.lock():
+ pickstate = state.cmdstate(repo, path=b'pickstate')
+ pickstate.load()
+ orignode = pickstate[b'orignode']
+ origctx = repo[orignode]
+ return _dopick(ui, repo, pickstate, orignode, origctx)
def abortpick(ui, repo, pickstate, abortcmd=False):
"""logic to abort pick"""
@@ -1576,6 +1589,13 @@ def continuefixup(ui, repo, fixup_state)
compat.update(repo.unfiltered()[tempnode])
return 0
+def hgcontinuefixup(ui, repo):
+ """logic for handling `hg continue' for fixup"""
+ with repo.wlock(), repo.lock():
+ fixup_state = state.cmdstate(repo, b'fixup-state')
+ fixup_state.load()
+ return continuefixup(ui, repo, fixup_state)
+
def abortfixup(ui, repo, fixup_state):
"""logic for handling of `hg fixup --abort`"""
with repo.wlock(), repo.lock():
@@ -1594,3 +1614,10 @@ def abortfixup(ui, repo, fixup_state):
ui.status(_(b'working directory is now at %s\n') % pctx)
fixup_state.delete()
return 0
+
+def hgabortfixup(ui, repo):
+ """logic for handling `hg abort' for fixup"""
+ with repo.wlock(), repo.lock():
+ fixup_state = state.cmdstate(repo, b'fixup-state')
+ fixup_state.load()
+ return abortfixup(ui, repo, fixup_state)
diff --git a/hgext3rd/evolve/evolvecmd.py b/hgext3rd/evolve/evolvecmd.py
--- a/hgext3rd/evolve/evolvecmd.py
+++ b/hgext3rd/evolve/evolvecmd.py
@@ -2047,6 +2047,23 @@ def continueevolve(ui, repo, evolvestate
progress.complete()
return headnode
+def hgcontinueevolve(ui, repo):
+ """logic for continuing evolve using 'hg continue'"""
+ with repo.wlock(), repo.lock():
+ evolvestate = state.cmdstate(repo)
+ evolvestate.load()
+ headnode = continueevolve(ui, repo, evolvestate)
+ if evolvestate[b'command'] != b'evolve':
+ evolvestate.delete()
+ return
+ startnode = evolvestate[b'startnode']
+ shouldupdate = False
+ if b'update' in evolvestate:
+ shouldupdate = evolvestate[b'update']
+ evolvestate.delete()
+
+ _cleanup(ui, repo, startnode, shouldupdate, headnode)
+
def _continuecontentdivergent(ui, repo, evolvestate, progresscb):
"""function to continue the interrupted content-divergence resolution."""
tr = repo.transaction(b'evolve')
diff --git a/tests/test-abort.t b/tests/test-abort.t
new file mode 100644
--- /dev/null
+++ b/tests/test-abort.t
@@ -0,0 +1,116 @@
+Test for hg abort support
+
+ $ cat >> $HGRCPATH <<EOF
+ > [alias]
+ > glog = log -G -T "{rev}:{node|short} {desc}\n"
+ > glf = log -GT "{rev}: {desc} ({files})\n"
+ > [extensions]
+ > EOF
+ $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
+
+ $ mkcommit() {
+ > echo "$1" > "$1"
+ > hg add "$1"
+ > hg ci -m "add $1"
+ > }
+
+ $ hg init repo
+ $ cd repo
+
+ $ mkcommit a
+ $ mkcommit b
+ $ mkcommit c
+
+ $ hg glog
+ @ 2:4538525df7e2 add c
+ |
+ o 1:7c3bad9141dc add b
+ |
+ o 0:1f0dee641bb7 add a
+
+
+Test hg abort with pick
+
+ $ hg up 'desc("add a")'
+ 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+
+ $ echo conflict > b
+ $ echo conflict > c
+ $ hg ci -Aqm "conflict b/c"
+ $ hg pick -r 'desc("add b")'
+ picking 1:7c3bad9141dc "add b"
+ merging b
+ warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
+ unresolved merge conflicts (see hg help resolve)
+ [240]
+ $ echo merged > b
+ $ hg resolve --all --mark
+ (no more unresolved files)
+ continue: hg pick --continue
+ $ hg abort
+ pick aborted
+ working directory is now at 2edd1d9ca33f
+ $ hg glog
+ @ 3:2edd1d9ca33f conflict b/c
+ |
+ | o 2:4538525df7e2 add c
+ | |
+ | o 1:7c3bad9141dc add b
+ |/
+ o 0:1f0dee641bb7 add a
+
+Test hg abort with evolve
+
+ $ hg prune -r 'desc("add b")' -s 'desc("conflict b/c")'
+ 1 changesets pruned
+ 1 new orphan changesets
+ $ hg evolve
+ move:[2] add c
+ atop:[3] conflict b/c
+ merging c
+ warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
+ unresolved merge conflicts
+ (see 'hg help evolve.interrupted')
+ [240]
+ $ hg abort
+ evolve aborted
+ working directory is now at 2edd1d9ca33f
+ $ hg glog
+ @ 3:2edd1d9ca33f conflict b/c
+ |
+ | * 2:4538525df7e2 add c
+ | |
+ | x 1:7c3bad9141dc add b
+ |/
+ o 0:1f0dee641bb7 add a
+
+
+Test hg abort with fixup
+
+ $ echo hello >> b
+ $ hg ci -Aqm "add hello b"
+ $ echo conflict >> b
+ $ hg fix-up -r 'desc("conflict b/c")'
+ merging b
+ warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
+ unresolved merge conflicts
+ (see 'hg help evolve.interrupted')
+ [240]
+ $ hg resolve --all --mark
+ (no more unresolved files)
+ continue: hg fixup --continue
+ $ hg abort
+ fixup aborted
+ working directory is now at 821b31258e9b
+ $ hg glog
+ @ 4:821b31258e9b add hello b
+ |
+ o 3:2edd1d9ca33f conflict b/c
+ |
+ | * 2:4538525df7e2 add c
+ | |
+ | x 1:7c3bad9141dc add b
+ |/
+ o 0:1f0dee641bb7 add a
+
+
diff --git a/tests/test-continue.t b/tests/test-continue.t
new file mode 100644
--- /dev/null
+++ b/tests/test-continue.t
@@ -0,0 +1,121 @@
+Test for hg continue support
+
+ $ cat >> $HGRCPATH <<EOF
+ > [alias]
+ > glog = log -G -T "{rev}:{node|short} {desc}\n"
+ > glf = log -GT "{rev}: {desc} ({files})\n"
+ > [extensions]
+ > EOF
+ $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
+
+ $ mkcommit() {
+ > echo "$1" > "$1"
+ > hg add "$1"
+ > hg ci -m "add $1"
+ > }
+
+ $ hg init repo
+ $ cd repo
+
+ $ mkcommit a
+ $ mkcommit b
+ $ mkcommit c
+
+ $ hg glog
+ @ 2:4538525df7e2 add c
+ |
+ o 1:7c3bad9141dc add b
+ |
+ o 0:1f0dee641bb7 add a
+
+
+Test hg continue with pick
+
+ $ hg up 'desc("add a")'
+ 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+
+ $ echo conflict > b
+ $ echo conflict > c
+ $ hg ci -Aqm "conflict b/c"
+ $ hg pick -r 'desc("add b")'
+ picking 1:7c3bad9141dc "add b"
+ merging b
+ warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
+ unresolved merge conflicts (see hg help resolve)
+ [240]
+ $ echo merged > b
+ $ hg resolve --all --mark
+ (no more unresolved files)
+ continue: hg pick --continue
+ $ hg continue
+ 1 new orphan changesets
+ $ hg glog
+ @ 4:cb17a452ebae add b
+ |
+ o 3:2edd1d9ca33f conflict b/c
+ |
+ | * 2:4538525df7e2 add c
+ | |
+ | x 1:7c3bad9141dc add b
+ |/
+ o 0:1f0dee641bb7 add a
+
+Test hg continue with evolve
+
+ $ hg evolve
+ move:[2] add c
+ atop:[4] add b
+ merging c
+ warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
+ unresolved merge conflicts
+ (see 'hg help evolve.interrupted')
+ [240]
+ $ echo merged > c
+ $ hg resolve --all --mark
+ (no more unresolved files)
+ continue: hg evolve --continue
+ $ hg continue
+ evolving 2:4538525df7e2 "add c"
+ $ hg glog
+ o 5:ba2a3cf75863 add c
+ |
+ @ 4:cb17a452ebae add b
+ |
+ o 3:2edd1d9ca33f conflict b/c
+ |
+ o 0:1f0dee641bb7 add a
+
+
+Test hg continue with fixup
+
+ $ echo hello >> b
+ $ hg ci -Aqm "add hello b"
+ $ echo conflict >> b
+ $ hg fix-up -r 'desc("conflict b/c")'
+ merging b
+ warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
+ unresolved merge conflicts
+ (see 'hg help evolve.interrupted')
+ [240]
+ $ hg resolve --all --mark
+ (no more unresolved files)
+ continue: hg fixup --continue
+ $ hg continue
+ evolving 7:879308e8b4ce "temporary fixup commit"
+ 3 new orphan changesets
+ $ hg glog
+ o 9:fe8ff2cf1f6a conflict b/c
+ |
+ | @ 7:879308e8b4ce temporary fixup commit
+ | |
+ | * 6:4202b8dd5346 add hello b
+ | |
+ | | * 5:ba2a3cf75863 add c
+ | |/
+ | * 4:cb17a452ebae add b
+ | |
+ | x 3:2edd1d9ca33f conflict b/c
+ |/
+ o 0:1f0dee641bb7 add a
+
+
diff --git a/tests/test-evolve-progress.t b/tests/test-evolve-progress.t
--- a/tests/test-evolve-progress.t
+++ b/tests/test-evolve-progress.t
@@ -188,4 +188,82 @@ Test progress with --continue
getting a
updating: a 2/2 files (100.00%)
+Test progress with hg continue
+ $ hg co -q 'desc("first")'
+ $ echo conflict2 > a
+ $ hg amend -m 'first v5'
+ 3 new orphan changesets
+ $ hg evolve --all --config progress.debug=yes --debug
+ evolve: 1/3 changesets (33.33%)
+ move:[11] second
+ atop:[14] first v5
+ hg rebase -r 60a86497fbfe -d 0cbc15354f23
+ evolve: 1/3 changesets (33.33%)
+ resolving manifests
+ branchmerge: True, force: True, partial: False
+ ancestor: f8d7d38c0a88, local: 0cbc15354f23+, remote: 60a86497fbfe
+ starting 4 threads for background file closing (?)
+ preserving a for resolve of a
+ a: versions differ -> m
+ updating: a 1/1 files (100.00%)
+ picked tool ':merge' for a (binary False symlink False changedelete False)
+ merging a
+ my a at 0cbc15354f23+ other a at 60a86497fbfe ancestor a at f8d7d38c0a88
+ warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
+ unresolved merge conflicts
+ (see 'hg help evolve.interrupted')
+ [240]
+ $ echo resolved > a
+ $ hg resolve -m a
+ (no more unresolved files)
+ continue: hg evolve --continue
+ $ hg continue --config progress.debug=yes --debug
+ evolving 11:60a86497fbfe "second"
+ committing files:
+ a
+ committing manifest
+ committing changelog
+ updating the branch cache
+ obscache is out of date
+ move:[12] third
+ atop:[15] second
+ hg rebase -r b2de95304e32 -d 8d7767a678b3
+ evolve: 2/3 changesets (66.67%)
+ resolving manifests
+ branchmerge: True, force: True, partial: False
+ ancestor: 60a86497fbfe, local: 8d7767a678b3+, remote: b2de95304e32
+ b: remote created -> g
+ getting b
+ updating: b 1/1 files (100.00%)
+ committing files:
+ b
+ committing manifest
+ committing changelog
+ move:[13] fourth
+ hg rebase -r c6e6fdb1d046 -d 97af772a84aa
+ evolve: 3/3 changesets (100.00%)
+ resolving manifests
+ branchmerge: True, force: True, partial: False
+ ancestor: b2de95304e32, local: 97af772a84aa+, remote: c6e6fdb1d046
+ b: remote is newer -> g
+ getting b
+ updating: b 1/1 files (100.00%)
+ committing files:
+ b
+ committing manifest
+ committing changelog
+ updating the branch cache
+ obscache is out of date
+ invalid branch cache (served): tip differs
+ invalid branch cache (served.hidden): tip differs
+ resolving manifests
+ branchmerge: False, force: False, partial: False
+ ancestor: 2a62ff95fd62, local: 2a62ff95fd62+, remote: 0cbc15354f23
+ b: other deleted -> r
+ removing b
+ updating: b 1/2 files (50.00%)
+ a: remote is newer -> g
+ getting a
+ updating: a 2/2 files (100.00%)
+
$ cd ..
More information about the Mercurial-devel
mailing list