[Commented On] D10963: dirstate: move the handling of special case within the dirstatemap

baymax (Baymax, Your Personal Patch-care Companion) phabricator at mercurial-scm.org
Tue Jul 6 18:15:18 UTC 2021


baymax added a comment.
baymax updated this revision to Diff 28865.


  ✅ refresh by Heptapod after a successful CI run (🐙 💚)

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D10963?vs=28784&id=28865

BRANCH
  default

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

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

AFFECTED FILES
  mercurial/dirstate.py
  mercurial/dirstatemap.py
  rust/hg-core/src/dirstate.rs
  rust/hg-core/src/dirstate/dirstate_map.rs
  rust/hg-core/src/dirstate_tree/dirstate_map.rs
  rust/hg-core/src/dirstate_tree/dispatch.rs
  rust/hg-cpython/src/dirstate/dirstate_map.rs
  rust/hg-cpython/src/dirstate/dispatch.rs

CHANGE DETAILS

diff --git a/rust/hg-cpython/src/dirstate/dispatch.rs b/rust/hg-cpython/src/dirstate/dispatch.rs
--- a/rust/hg-cpython/src/dirstate/dispatch.rs
+++ b/rust/hg-cpython/src/dirstate/dispatch.rs
@@ -26,8 +26,16 @@
         filename: &HgPath,
         old_state: EntryState,
         entry: DirstateEntry,
+        from_p2: bool,
+        possibly_dirty: bool,
     ) -> Result<(), DirstateError> {
-        self.get_mut().add_file(filename, old_state, entry)
+        self.get_mut().add_file(
+            filename,
+            old_state,
+            entry,
+            from_p2,
+            possibly_dirty,
+        )
     }
 
     fn remove_file(
diff --git a/rust/hg-cpython/src/dirstate/dirstate_map.rs b/rust/hg-cpython/src/dirstate/dirstate_map.rs
--- a/rust/hg-cpython/src/dirstate/dirstate_map.rs
+++ b/rust/hg-cpython/src/dirstate/dirstate_map.rs
@@ -28,6 +28,8 @@
 };
 use hg::{
     dirstate::parsers::Timestamp,
+    dirstate::MTIME_UNSET,
+    dirstate::SIZE_NON_NORMAL,
     dirstate_tree::dispatch::DirstateMapMethods,
     dirstate_tree::on_disk::DirstateV2ParseError,
     errors::HgError,
@@ -110,7 +112,9 @@
         state: PyObject,
         mode: PyObject,
         size: PyObject,
-        mtime: PyObject
+        mtime: PyObject,
+        from_p2: PyObject,
+        possibly_dirty: PyObject,
     ) -> PyResult<PyObject> {
         let f = f.extract::<PyBytes>(py)?;
         let filename = HgPath::new(f.data(py));
@@ -125,18 +129,32 @@
                 PyErr::new::<exc::ValueError, _>(py, e.to_string())
             })?;
         let mode = mode.extract(py)?;
-        let size = size.extract(py)?;
-        let mtime = mtime.extract(py)?;
+        let size = if size.is_none(py) {
+            // fallback default value
+            SIZE_NON_NORMAL
+        } else {
+            size.extract(py)?
+        };
+        let mtime = if mtime.is_none(py) {
+            // fallback default value
+            MTIME_UNSET
+        } else {
+            mtime.extract(py)?
+        };
         let entry = DirstateEntry {
             state: state,
             mode: mode,
             size: size,
             mtime: mtime,
         };
+        let from_p2 = from_p2.extract::<PyBool>(py)?.is_true();
+        let possibly_dirty = possibly_dirty.extract::<PyBool>(py)?.is_true();
         self.inner(py).borrow_mut().add_file(
             filename,
             oldstate,
             entry,
+            from_p2,
+            possibly_dirty
         ).and(Ok(py.None())).or_else(|e: DirstateError| {
             Err(PyErr::new::<exc::ValueError, _>(py, e.to_string()))
         })
diff --git a/rust/hg-core/src/dirstate_tree/dispatch.rs b/rust/hg-core/src/dirstate_tree/dispatch.rs
--- a/rust/hg-core/src/dirstate_tree/dispatch.rs
+++ b/rust/hg-core/src/dirstate_tree/dispatch.rs
@@ -49,6 +49,8 @@
         filename: &HgPath,
         old_state: EntryState,
         entry: DirstateEntry,
+        from_p2: bool,
+        possibly_dirty: bool,
     ) -> Result<(), DirstateError>;
 
     /// Mark a file as "removed" (as in `hg rm`).
@@ -287,8 +289,10 @@
         filename: &HgPath,
         old_state: EntryState,
         entry: DirstateEntry,
+        from_p2: bool,
+        possibly_dirty: bool,
     ) -> Result<(), DirstateError> {
-        self.add_file(filename, old_state, entry)
+        self.add_file(filename, old_state, entry, from_p2, possibly_dirty)
     }
 
     fn remove_file(
diff --git a/rust/hg-core/src/dirstate_tree/dirstate_map.rs b/rust/hg-core/src/dirstate_tree/dirstate_map.rs
--- a/rust/hg-core/src/dirstate_tree/dirstate_map.rs
+++ b/rust/hg-core/src/dirstate_tree/dirstate_map.rs
@@ -11,8 +11,10 @@
 use crate::dirstate::parsers::packed_entry_size;
 use crate::dirstate::parsers::parse_dirstate_entries;
 use crate::dirstate::parsers::Timestamp;
+use crate::dirstate::MTIME_UNSET;
 use crate::dirstate::SIZE_FROM_OTHER_PARENT;
 use crate::dirstate::SIZE_NON_NORMAL;
+use crate::dirstate::V1_RANGEMASK;
 use crate::matchers::Matcher;
 use crate::utils::hg_path::{HgPath, HgPathBuf};
 use crate::CopyMapIter;
@@ -721,7 +723,27 @@
         filename: &HgPath,
         old_state: EntryState,
         entry: DirstateEntry,
+        from_p2: bool,
+        possibly_dirty: bool,
     ) -> Result<(), DirstateError> {
+        let mut entry = entry;
+        if entry.state == EntryState::Added {
+            assert!(!possibly_dirty);
+            assert!(!from_p2);
+            entry.size = SIZE_NON_NORMAL;
+            entry.mtime = MTIME_UNSET;
+        } else if from_p2 {
+            assert!(!possibly_dirty);
+            entry.size = SIZE_FROM_OTHER_PARENT;
+            entry.mtime = MTIME_UNSET;
+        } else if possibly_dirty {
+            entry.size = SIZE_NON_NORMAL;
+            entry.mtime = MTIME_UNSET;
+        } else {
+            entry.size = entry.size & V1_RANGEMASK;
+            entry.mtime = entry.mtime & V1_RANGEMASK;
+        }
+
         Ok(self.add_or_remove_file(filename, old_state, entry)?)
     }
 
diff --git a/rust/hg-core/src/dirstate/dirstate_map.rs b/rust/hg-core/src/dirstate/dirstate_map.rs
--- a/rust/hg-core/src/dirstate/dirstate_map.rs
+++ b/rust/hg-core/src/dirstate/dirstate_map.rs
@@ -8,8 +8,10 @@
 use crate::dirstate::parsers::Timestamp;
 use crate::{
     dirstate::EntryState,
+    dirstate::MTIME_UNSET,
     dirstate::SIZE_FROM_OTHER_PARENT,
     dirstate::SIZE_NON_NORMAL,
+    dirstate::V1_RANGEMASK,
     pack_dirstate, parse_dirstate,
     utils::hg_path::{HgPath, HgPathBuf},
     CopyMap, DirsMultiset, DirstateEntry, DirstateError, DirstateParents,
@@ -68,7 +70,28 @@
         filename: &HgPath,
         old_state: EntryState,
         entry: DirstateEntry,
+        // XXX once the dust settle this should probably become an enum
+        from_p2: bool,
+        possibly_dirty: bool,
     ) -> Result<(), DirstateError> {
+        let mut entry = entry;
+        if entry.state == EntryState::Added {
+            assert!(!possibly_dirty);
+            assert!(!from_p2);
+            entry.size = SIZE_NON_NORMAL;
+            entry.mtime = MTIME_UNSET;
+        } else if from_p2 {
+            assert!(!possibly_dirty);
+            entry.size = SIZE_FROM_OTHER_PARENT;
+            entry.mtime = MTIME_UNSET;
+        } else if possibly_dirty {
+            entry.size = SIZE_NON_NORMAL;
+            entry.mtime = MTIME_UNSET;
+        } else {
+            entry.size = entry.size & V1_RANGEMASK;
+            entry.mtime = entry.mtime & V1_RANGEMASK;
+        }
+
         if old_state == EntryState::Unknown || old_state == EntryState::Removed
         {
             if let Some(ref mut dirs) = self.dirs {
@@ -381,6 +404,8 @@
                 mtime: 1337,
                 size: 1337,
             },
+            false,
+            false,
         )
         .unwrap();
 
diff --git a/rust/hg-core/src/dirstate.rs b/rust/hg-core/src/dirstate.rs
--- a/rust/hg-core/src/dirstate.rs
+++ b/rust/hg-core/src/dirstate.rs
@@ -77,6 +77,8 @@
     length: unaligned::I32Be,
 }
 
+pub const V1_RANGEMASK: i32 = 0x7FFFFFFF;
+
 pub const MTIME_UNSET: i32 = -1;
 
 /// A `DirstateEntry` with a size of `-2` means that it was merged from the
diff --git a/mercurial/dirstatemap.py b/mercurial/dirstatemap.py
--- a/mercurial/dirstatemap.py
+++ b/mercurial/dirstatemap.py
@@ -35,6 +35,8 @@
 # a special value used internally for `time` if the time is ambigeous
 AMBIGUOUS_TIME = -1
 
+rangemask = 0x7FFFFFFF
+
 
 class dirstatemap(object):
     """Map encapsulating the dirstate's contents.
@@ -142,8 +144,37 @@
         """Loads the underlying data, if it's not already loaded"""
         self._map
 
-    def addfile(self, f, oldstate, state, mode, size, mtime):
+    def addfile(
+        self,
+        f,
+        oldstate,
+        state,
+        mode,
+        size=None,
+        mtime=None,
+        from_p2=False,
+        possibly_dirty=False,
+    ):
         """Add a tracked file to the dirstate."""
+        if state == b'a':
+            assert not possibly_dirty
+            assert not from_p2
+            size = NONNORMAL
+            mtime = AMBIGUOUS_TIME
+        elif from_p2:
+            assert not possibly_dirty
+            size = FROM_P2
+            mtime = AMBIGUOUS_TIME
+        elif possibly_dirty:
+            size = NONNORMAL
+            mtime = AMBIGUOUS_TIME
+        else:
+            assert size != FROM_P2
+            assert size != NONNORMAL
+            size = size & rangemask
+            mtime = mtime & rangemask
+        assert size is not None
+        assert mtime is not None
         if oldstate in b"?r" and "_dirs" in self.__dict__:
             self._dirs.addpath(f)
         if oldstate == b"?" and "_alldirs" in self.__dict__:
@@ -425,8 +456,27 @@
                 False,
             )
 
-        def addfile(self, *args, **kwargs):
-            return self._rustmap.addfile(*args, **kwargs)
+        def addfile(
+            self,
+            f,
+            oldstate,
+            state,
+            mode,
+            size=None,
+            mtime=None,
+            from_p2=False,
+            possibly_dirty=False,
+        ):
+            return self._rustmap.addfile(
+                f,
+                oldstate,
+                state,
+                mode,
+                size,
+                mtime,
+                from_p2,
+                possibly_dirty,
+            )
 
         def removefile(self, *args, **kwargs):
             return self._rustmap.removefile(*args, **kwargs)
diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py
--- a/mercurial/dirstate.py
+++ b/mercurial/dirstate.py
@@ -43,11 +43,10 @@
 
 propertycache = util.propertycache
 filecache = scmutil.filecache
-_rangemask = 0x7FFFFFFF
+_rangemask = dirstatemap.rangemask
 
 dirstatetuple = parsers.dirstatetuple
 
-
 # a special value used internally for `size` if the file come from the other parent
 FROM_P2 = dirstatemap.FROM_P2
 
@@ -455,8 +454,8 @@
         f,
         state,
         mode,
-        size=NONNORMAL,
-        mtime=AMBIGUOUS_TIME,
+        size=None,
+        mtime=None,
         from_p2=False,
         possibly_dirty=False,
     ):
@@ -476,25 +475,18 @@
                     msg = _(b'file %r in dirstate clashes with %r')
                     msg %= (pycompat.bytestr(d), pycompat.bytestr(f))
                     raise error.Abort(msg)
-        if state == b'a':
-            assert not possibly_dirty
-            assert not from_p2
-            size = NONNORMAL
-            mtime = AMBIGUOUS_TIME
-        elif from_p2:
-            assert not possibly_dirty
-            size = FROM_P2
-            mtime = AMBIGUOUS_TIME
-        elif possibly_dirty:
-            mtime = AMBIGUOUS_TIME
-        else:
-            assert size != FROM_P2
-            assert size != NONNORMAL
-            size = size & _rangemask
-            mtime = mtime & _rangemask
         self._dirty = True
         self._updatedfiles.add(f)
-        self._map.addfile(f, oldstate, state, mode, size, mtime)
+        self._map.addfile(
+            f,
+            oldstate,
+            state=state,
+            mode=mode,
+            size=size,
+            mtime=mtime,
+            from_p2=from_p2,
+            possibly_dirty=possibly_dirty,
+        )
 
     def normal(self, f, parentfiledata=None):
         """Mark a file normal and clean.



To: marmoute, #hg-reviewers, SimonSapin, pulkit
Cc: mercurial-patches
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurial-scm.org/pipermail/mercurial-patches/attachments/20210706/dd478ec4/attachment-0002.html>


More information about the Mercurial-patches mailing list