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
--- 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)