changeset 48002:4e6f27230aee

dirstate: introduce a `set_clean` method on dirstate's map and items This method is the "reverse" of "set possibly dirty", and can be used to more accurately other call that the dirstate was making. It is currently heavily influenced by its origin. Differential Revision: https://phab.mercurial-scm.org/D11421
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Thu, 02 Sep 2021 03:59:35 +0200
parents 2e0ff3947b05
children ec178161a8d1
files mercurial/cext/parsers.c mercurial/dirstate.py mercurial/dirstatemap.py mercurial/pure/parsers.py rust/Cargo.lock
diffstat 5 files changed, 56 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/cext/parsers.c	Thu Sep 02 04:03:20 2021 +0200
+++ b/mercurial/cext/parsers.c	Thu Sep 02 03:59:35 2021 +0200
@@ -492,6 +492,21 @@
 	}
 }
 
+/* See docstring of the python implementation for details */
+static PyObject *dirstate_item_set_clean(dirstateItemObject *self,
+                                         PyObject *args)
+{
+	int size, mode, mtime;
+	if (!PyArg_ParseTuple(args, "iii", &mode, &size, &mtime)) {
+		return NULL;
+	}
+	self->flags = dirstate_flag_wc_tracked | dirstate_flag_p1_tracked;
+	self->mode = mode;
+	self->size = size;
+	self->mtime = mtime;
+	Py_RETURN_NONE;
+}
+
 static PyObject *dirstate_item_set_untracked(dirstateItemObject *self)
 {
 	self->flags &= ~dirstate_flag_wc_tracked;
@@ -531,6 +546,8 @@
      "constructor to help legacy API to build a new \"normal\" item"},
     {"set_possibly_dirty", (PyCFunction)dirstate_item_set_possibly_dirty,
      METH_NOARGS, "mark a file as \"possibly dirty\""},
+    {"set_clean", (PyCFunction)dirstate_item_set_clean, METH_VARARGS,
+     "mark a file as \"clean\""},
     {"set_untracked", (PyCFunction)dirstate_item_set_untracked, METH_NOARGS,
      "mark a file as \"untracked\""},
     {NULL} /* Sentinel */
--- a/mercurial/dirstate.py	Thu Sep 02 04:03:20 2021 +0200
+++ b/mercurial/dirstate.py	Thu Sep 02 03:59:35 2021 +0200
@@ -508,10 +508,9 @@
             (mode, size, mtime) = parentfiledata
         else:
             (mode, size, mtime) = self._get_filedata(filename)
-        self._addpath(filename, mode=mode, size=size, mtime=mtime)
-        self._map.copymap.pop(filename, None)
-        if filename in self._map.nonnormalset:
-            self._map.nonnormalset.remove(filename)
+        if not self._map[filename].tracked:
+            self._check_new_tracked_filename(filename)
+        self._map.set_clean(filename, mode, size, mtime)
         if mtime > self._lastnormaltime:
             # Remember the most recent modification timeslot for status(),
             # to make sure we won't miss future size-preserving file content
--- a/mercurial/dirstatemap.py	Thu Sep 02 04:03:20 2021 +0200
+++ b/mercurial/dirstatemap.py	Thu Sep 02 03:59:35 2021 +0200
@@ -162,6 +162,15 @@
         """record that the current state of the file on disk is unknown"""
         self[filename].set_possibly_dirty()
 
+    def set_clean(self, filename, mode, size, mtime):
+        """mark a file as back to a clean state"""
+        entry = self[filename]
+        mtime = mtime & rangemask
+        size = size & rangemask
+        entry.set_clean(mode, size, mtime)
+        self.copymap.pop(filename, None)
+        self.nonnormalset.discard(filename)
+
     def addfile(
         self,
         f,
@@ -924,6 +933,15 @@
             entry.set_possibly_dirty()
             self._rustmap.set_v1(filename, entry)
 
+        def set_clean(self, filename, mode, size, mtime):
+            """mark a file as back to a clean state"""
+            entry = self[filename]
+            mtime = mtime & rangemask
+            size = size & rangemask
+            entry.set_clean(mode, size, mtime)
+            self._rustmap.set_v1(filename, entry)
+            self._rustmap.copymap().pop(filename, None)
+
         def __setitem__(self, key, value):
             assert isinstance(value, DirstateItem)
             self._rustmap.set_v1(key, value)
--- a/mercurial/pure/parsers.py	Thu Sep 02 04:03:20 2021 +0200
+++ b/mercurial/pure/parsers.py	Thu Sep 02 03:59:35 2021 +0200
@@ -222,6 +222,24 @@
         """
         self._possibly_dirty = True
 
+    def set_clean(self, mode, size, mtime):
+        """mark a file as "clean" cancelling potential "possibly dirty call"
+
+        Note: this function is a descendant of `dirstate.normal` and is
+        currently expected to be call on "normal" entry only. There are not
+        reason for this to not change in the future as long as the ccode is
+        updated to preserve the proper state of the non-normal files.
+        """
+        self._wc_tracked = True
+        self._p1_tracked = True
+        self._p2_tracked = False  # this might be wrong
+        self._merged = False
+        self._clean_p2 = False
+        self._possibly_dirty = False
+        self._mode = mode
+        self._size = size
+        self._mtime = mtime
+
     def set_untracked(self):
         """mark a file as untracked in the working copy
 
--- a/rust/Cargo.lock	Thu Sep 02 04:03:20 2021 +0200
+++ b/rust/Cargo.lock	Thu Sep 02 03:59:35 2021 +0200
@@ -1,7 +1,5 @@
 # This file is automatically @generated by Cargo.
 # It is not intended for manual editing.
-version = 3
-
 [[package]]
 name = "adler"
 version = "0.2.3"