# HG changeset patch # User Martin von Zweigbergk # Date 1600211416 25200 # Node ID 19590b126764ccdc4d5edbea35d0f7fd51bb2cbe # Parent cc5f811b1f155d917ed7d4ffc06b00a223c3eab7 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 diff -r cc5f811b1f15 -r 19590b126764 mercurial/context.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 diff -r cc5f811b1f15 -r 19590b126764 mercurial/merge.py --- 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"), diff -r cc5f811b1f15 -r 19590b126764 mercurial/mergestate.py --- 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)