rebase: teach in-memory rebase to not restart with on-disk rebase on conflict
When in-memory rebase runs into conflicts, it redoes the whole rebase
operation. This patch teaches it to instead discard just the current
`overlayworkingctx` and redo that node on disk.
I've tested this by enabling in-memory rebase by default and checking
that there are no unexpected differences after this patch.
The next step is to make it so that `hg rebase --continue` can use
in-memory merge.
Differential Revision: https://phab.mercurial-scm.org/D9076
--- a/hgext/rebase.py Thu Sep 24 16:30:17 2020 +0200
+++ b/hgext/rebase.py Fri Sep 18 15:03:06 2020 -0700
@@ -615,9 +615,49 @@
else:
overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
with ui.configoverride(overrides, b'rebase'):
- rebasenode(
- repo, rev, p1, p2, base, self.collapsef, wctx=self.wctx,
- )
+ try:
+ rebasenode(
+ repo,
+ rev,
+ p1,
+ p2,
+ base,
+ self.collapsef,
+ wctx=self.wctx,
+ )
+ except error.InMemoryMergeConflictsError:
+ if self.dryrun:
+ raise error.ConflictResolutionRequired(b'rebase')
+ if self.collapsef:
+ # TODO: Make the overlayworkingctx reflected
+ # in the working copy here instead of re-raising
+ # so the entire rebase operation is retried.
+ raise
+ ui.status(
+ _(
+ b"hit merge conflicts; rebasing that "
+ b"commit again in the working copy\n"
+ )
+ )
+ cmdutil.bailifchanged(repo)
+ self.inmemory = False
+ self._assignworkingcopy()
+ mergemod.update(
+ repo,
+ p1,
+ branchmerge=False,
+ force=False,
+ wc=self.wctx,
+ )
+ rebasenode(
+ repo,
+ rev,
+ p1,
+ p2,
+ base,
+ self.collapsef,
+ wctx=self.wctx,
+ )
if not self.collapsef:
merging = p2 != nullrev
editform = cmdutil.mergeeditform(merging, b'rebase')
@@ -1100,7 +1140,7 @@
_origrebase(
ui, repo, action, opts, rbsrt,
)
- except error.InMemoryMergeConflictsError:
+ except error.ConflictResolutionRequired:
ui.status(_(b'hit a merge conflict\n'))
return 1
except error.Abort:
--- a/tests/test-rebase-inmemory.t Thu Sep 24 16:30:17 2020 +0200
+++ b/tests/test-rebase-inmemory.t Fri Sep 18 15:03:06 2020 -0700
@@ -415,8 +415,6 @@
rebasing 3:055a42cdd887 "d"
rebasing 4:e860deea161a "e"
merging e
- transaction abort!
- rollback completed
hit a merge conflict
[1]
$ hg diff
@@ -463,12 +461,7 @@
rebasing 3:055a42cdd887 "d"
rebasing 4:e860deea161a "e"
merging e
- transaction abort!
- rollback completed
- hit merge conflicts; re-running rebase without in-memory merge
- rebasing 2:177f92b77385 "c"
- rebasing 3:055a42cdd887 "d"
- rebasing 4:e860deea161a "e"
+ hit merge conflicts; rebasing that commit again in the working copy
merging e
warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
@@ -487,9 +480,9 @@
rebasing 3:055a42cdd887 "d"
rebasing 4:e860deea161a "e"
merging e
+ hit merge conflicts; rebasing that commit again in the working copy
transaction abort!
rollback completed
- hit merge conflicts; re-running rebase without in-memory merge
abort: uncommitted changes
[255]
$ cat a
@@ -859,8 +852,7 @@
$ hg rebase -r . -d 1 --config ui.merge=internal:merge3
rebasing 2:fb62b706688e "add b to foo" (tip)
merging foo
- hit merge conflicts; re-running rebase without in-memory merge
- rebasing 2:fb62b706688e "add b to foo" (tip)
+ hit merge conflicts; rebasing that commit again in the working copy
merging foo
warning: conflicts while merging foo! (edit, then use 'hg resolve --mark')
unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
@@ -893,8 +885,7 @@
$ hg rebase -r 2 -d 1 -t:merge3
rebasing 2:b4d249fbf8dd "bye from foo"
merging foo
- hit merge conflicts; re-running rebase without in-memory merge
- rebasing 2:b4d249fbf8dd "bye from foo"
+ hit merge conflicts; rebasing that commit again in the working copy
merging foo
warning: conflicts while merging foo! (edit, then use 'hg resolve --mark')
unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')