[Updated] [++- ] D8567: mergestate: implement trivial in-memory mergestate

durin42 (Augie Fackler) phabricator at mercurial-scm.org
Tue May 19 19:52:52 UTC 2020


durin42 updated this revision to Diff 21452.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8567?vs=21444&id=21452

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8567/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8567

AFFECTED FILES
  mercurial/mergestate.py

CHANGE DETAILS

diff --git a/mercurial/mergestate.py b/mercurial/mergestate.py
--- a/mercurial/mergestate.py
+++ b/mercurial/mergestate.py
@@ -85,7 +85,40 @@
 }
 
 
-class mergestate(object):
+class _basemergestate(object):
+    def __init__(self, repo):
+        self._repo = repo
+        self._readmergedriver = None
+
+    @util.propertycache
+    def mergedriver(self):
+        # protect against the following:
+        # - A configures a malicious merge driver in their hgrc, then
+        #   pauses the merge
+        # - A edits their hgrc to remove references to the merge driver
+        # - A gives a copy of their entire repo, including .hg, to B
+        # - B inspects .hgrc and finds it to be clean
+        # - B then continues the merge and the malicious merge driver
+        #  gets invoked
+        configmergedriver = self._repo.ui.config(
+            b'experimental', b'mergedriver'
+        )
+        if (
+            self._readmergedriver is not None
+            and self._readmergedriver != configmergedriver
+        ):
+            raise error.ConfigError(
+                _(b"merge driver changed since merge started"),
+                hint=_(b"revert merge driver change or abort merge"),
+            )
+
+        return configmergedriver
+
+    def reset(self, node=None, other=None, labels=None):
+        self._readmergedriver = None
+
+
+class mergestate(_basemergestate):
     '''track 3-way merge state of individual files
 
     The merge state is stored on disk when needed. Two files are used: one with
@@ -154,11 +187,12 @@
         """Initialize the merge state.
 
         Do not use this directly! Instead call read() or clean()."""
-        self._repo = repo
+        super(mergestate, self).__init__(repo)
         self._dirty = False
         self._labels = None
 
     def reset(self, node=None, other=None, labels=None):
+        super(mergestate, self).reset(node=node, other=other, labels=labels)
         self._state = {}
         self._stateextras = {}
         self._local = None
@@ -170,7 +204,6 @@
         if node:
             self._local = node
             self._other = other
-        self._readmergedriver = None
         if self.mergedriver:
             self._mdstate = MERGE_DRIVER_STATE_SUCCESS
         else:
@@ -355,30 +388,6 @@
         return records
 
     @util.propertycache
-    def mergedriver(self):
-        # protect against the following:
-        # - A configures a malicious merge driver in their hgrc, then
-        #   pauses the merge
-        # - A edits their hgrc to remove references to the merge driver
-        # - A gives a copy of their entire repo, including .hg, to B
-        # - B inspects .hgrc and finds it to be clean
-        # - B then continues the merge and the malicious merge driver
-        #  gets invoked
-        configmergedriver = self._repo.ui.config(
-            b'experimental', b'mergedriver'
-        )
-        if (
-            self._readmergedriver is not None
-            and self._readmergedriver != configmergedriver
-        ):
-            raise error.ConfigError(
-                _(b"merge driver changed since merge started"),
-                hint=_(b"revert merge driver change or abort merge"),
-            )
-
-        return configmergedriver
-
-    @util.propertycache
     def local(self):
         if self._local is None:
             msg = b"local accessed but self._local isn't set"
@@ -857,3 +866,44 @@
             repo.dirstate.copy(f0, f)
         else:
             repo.dirstate.normal(f)
+
+
+class memmergestate(_basemergestate):
+    def __init__(self, repo):
+        super(memmergestate, self).__init__(repo)
+        self.reset()
+
+    def add(self, fcl, fco, fca, fd):
+        """add a new (potentially?) conflicting file to the merge state"""
+        self._conflicts.add(fcl.path())
+
+    # Since memmergestate isn't mutable yet, these are all trivial
+    # implementations used by the "happy path" in merge code.
+    def reset(self, node=None, other=None, labels=None):
+        super(memmergestate, self).reset(node=node, other=other, labels=labels)
+        self._conflicts = set()
+
+    def commit(self):
+        if self._conflicts:
+            error.InMemoryMergeConflictsError(
+                'cannot commit memmergestate with conflicts, have %d conflicts'
+                % self.unresolvedcount()
+            )
+
+    def counts(self):
+        return 0, 0, 0
+
+    def unresolvedcount(self):
+        return len(self._conflicts)
+
+    def actions(self):
+        return {}
+
+    @property
+    def mergedriver(self):
+        md = super(memmergestate, self).mergedriver
+        if md:
+            raise error.InMemoryMergeConflictsError(
+                b"in-memory merge does not support mergedriver"
+            )
+        return md



To: durin42, #hg-reviewers
Cc: martinvonz, mercurial-patches
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurial-scm.org/pipermail/mercurial-patches/attachments/20200519/9b336377/attachment-0002.html>


More information about the Mercurial-patches mailing list