merge: use in-memory mergestate when using in-memory context
authorMartin von Zweigbergk <martinvonz@google.com>
Tue, 15 Sep 2020 16:10:16 -0700
changeset 45499 19590b126764
parent 45498 cc5f811b1f15
child 45500 f2efc44213ec
merge: use in-memory mergestate when using in-memory context This is my version of Augie's D8568. It makes it so we don't touch the mergestate on disk when using an in-memory context. The reason that I want this is not the same as the reason that Augie write his patch (though I agree with that reason too). My hope is to make in-memory rebase not fall back to on-disk rebase when there are conflict. I plan to do that by adding a `overlayworkingctx.reflect_in_workingcopy()`. The idea is that that will update the working copy, the dirstate and the mergestate as necessary. Differential Revision: https://phab.mercurial-scm.org/D9040
mercurial/context.py
mercurial/merge.py
mercurial/mergestate.py
--- a/mercurial/context.py	Tue Sep 15 11:17:24 2020 -0700
+++ b/mercurial/context.py	Tue Sep 15 16:10:16 2020 -0700
@@ -2528,6 +2528,7 @@
         return path in self._cache
 
     def clean(self):
+        self._mergestate = None
         self._cache = {}
 
     def _compact(self):
@@ -2592,6 +2593,11 @@
             self._repo, path, parent=self, filelog=filelog
         )
 
+    def mergestate(self, clean=False):
+        if clean or self._mergestate is None:
+            self._mergestate = mergestatemod.memmergestate(self._repo)
+        return self._mergestate
+
 
 class overlayworkingfilectx(committablefilectx):
     """Wrap a ``workingfilectx`` but intercepts all writes into an in-memory
--- a/mercurial/merge.py	Tue Sep 15 11:17:24 2020 -0700
+++ b/mercurial/merge.py	Tue Sep 15 16:10:16 2020 -0700
@@ -1398,7 +1398,7 @@
     _prefetchfiles(repo, mctx, mresult)
 
     updated, merged, removed = 0, 0, 0
-    ms = mergestatemod.mergestate.clean(repo)
+    ms = wctx.mergestate(clean=True)
     ms.start(wctx.p1().node(), mctx.node(), labels)
 
     for f, op in pycompat.iteritems(mresult.commitinfo):
@@ -1611,10 +1611,6 @@
     usemergedriver = not overwrite and mergeactions and ms.mergedriver
 
     if usemergedriver:
-        if wctx.isinmemory():
-            raise error.InMemoryMergeConflictsError(
-                b"in-memory merge does not support mergedriver"
-            )
         ms.commit()
         proceed = driverpreprocess(repo, ms, wctx, labels=labels)
         # the driver might leave some files unresolved
@@ -1895,7 +1891,7 @@
         if not overwrite:
             if len(pl) > 1:
                 raise error.Abort(_(b"outstanding uncommitted merge"))
-            ms = mergestatemod.mergestate.read(repo)
+            ms = wc.mergestate()
             if list(ms.unresolved()):
                 raise error.Abort(
                     _(b"outstanding merge conflicts"),
--- a/mercurial/mergestate.py	Tue Sep 15 11:17:24 2020 -0700
+++ b/mercurial/mergestate.py	Tue Sep 15 16:10:16 2020 -0700
@@ -801,6 +801,32 @@
         shutil.rmtree(self._repo.vfs.join(b'merge'), True)
 
 
+class memmergestate(_mergestate_base):
+    def __init__(self, repo):
+        super(memmergestate, self).__init__(repo)
+        self._backups = {}
+
+    def _make_backup(self, fctx, localkey):
+        self._backups[localkey] = fctx.data()
+
+    def _restore_backup(self, fctx, localkey, flags):
+        fctx.write(self._backups[localkey], flags)
+
+    @util.propertycache
+    def mergedriver(self):
+        configmergedriver = self._repo.ui.config(
+            b'experimental', b'mergedriver'
+        )
+        if configmergedriver:
+            raise error.InMemoryMergeConflictsError(
+                b"in-memory merge does not support mergedriver"
+            )
+        return None
+
+    def commit(self):
+        pass
+
+
 def recordupdates(repo, actions, branchmerge, getfiledata):
     """record merge actions to the dirstate"""
     # remove (must come first)