diff hgext/rebase.py @ 45555:feffeb18d412

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
author Martin von Zweigbergk <martinvonz@google.com>
date Fri, 18 Sep 2020 15:03:06 -0700
parents e9468f14379a
children 03726f5b6092
line wrap: on
line diff
--- 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: