dirstate: add a `update_file` function
authorPierre-Yves David <pierre-yves.david@octobus.net>
Wed, 07 Jul 2021 19:36:14 +0200
changeset 47611 e2e72daac90b
parent 47610 f89d3050dcd5
child 47612 a9d75262b992
dirstate: add a `update_file` function This function is the other side of the `set_tracked`/`set_untracked` API revamp. It is to be used when the dirstate is changing its parents during and update or a merge. It states all the information we know about the file so that the dirstate can update its internal data. Unlike the `set_tracked`/`set_untracked` it has not regards for the information previously tracked in the tristate. Differential Revision: https://phab.mercurial-scm.org/D11075
mercurial/dirstate.py
--- a/mercurial/dirstate.py	Thu Jul 08 04:29:36 2021 +0200
+++ b/mercurial/dirstate.py	Wed Jul 07 19:36:14 2021 +0200
@@ -537,6 +537,62 @@
         else:
             assert False, 'unreachable'
 
+    @requires_parents_change
+    def update_file(
+        self,
+        filename,
+        wc_tracked,
+        p1_tracked,
+        p2_tracked=False,
+        merged=False,
+        clean_p1=False,
+        clean_p2=False,
+        possibly_dirty=False,
+    ):
+        """update the information about a file in the dirstate
+
+        This is to be called when the direstates parent changes to keep track
+        of what is the file situation in regards to the working copy and its parent.
+
+        This function must be called within a `dirstate.parentchange` context.
+
+        note: the API is at an early stage and we might need to ajust it
+        depending of what information ends up being relevant and useful to
+        other processing.
+        """
+        if not self.pendingparentchange():
+            msg = b'calling `update_file` outside of a parentchange context'
+            raise error.ProgrammingError(msg)
+        if merged and (clean_p1 or clean_p2):
+            msg = b'`merged` argument incompatible with `clean_p1`/`clean_p2`'
+            raise error.ProgrammingError(msg)
+        assert not (merged and (clean_p1 or clean_p1))
+        if not (p1_tracked or p2_tracked or wc_tracked):
+            self._drop(filename)
+        elif merged:
+            assert wc_tracked
+            if not self.in_merge:
+                self.normallookup(filename)
+            self.otherparent(filename)
+        elif not (p1_tracked or p2_tracked) and wc_tracked:
+            self._addpath(filename, added=True, possibly_dirty=possibly_dirty)
+            self._map.copymap.pop(filename, None)
+        elif (p1_tracked or p2_tracked) and not wc_tracked:
+            self._remove(filename)
+        elif clean_p2 and wc_tracked:
+            assert p2_tracked
+            self.otherparent(filename)
+        elif not p1_tracked and p2_tracked and wc_tracked:
+            self._addpath(filename, from_p2=True, possibly_dirty=possibly_dirty)
+            self._map.copymap.pop(filename, None)
+        elif possibly_dirty:
+            self._addpath(filename, possibly_dirty=possibly_dirty)
+        elif wc_tracked:
+            self.normal(filename)
+        # XXX We need something for file that are dirty after an update
+        else:
+            assert False, 'unreachable'
+
     def _addpath(
         self,
         f,