diff rust/hg-cpython/src/dirstate/dirstate_map.rs @ 52050:ea0467ed76aa

rust-dirstate-map: use a more precise identity This is closer to the behavior of what Python does. So far, we were checking only the inode, but this might not be good enough for the v1 case.
author Rapha?l Gom?s <rgomes@octobus.net>
date Thu, 03 Oct 2024 16:35:31 +0200
parents 0cd16b1d613f
children db065b33fa56
line wrap: on
line diff
--- a/rust/hg-cpython/src/dirstate/dirstate_map.rs	Mon Oct 14 14:14:21 2024 +0200
+++ b/rust/hg-cpython/src/dirstate/dirstate_map.rs	Thu Oct 03 16:35:31 2024 +0200
@@ -16,7 +16,9 @@
 };
 use hg::{
     dirstate::{ParentFileData, TruncatedTimestamp},
-    dirstate_tree::dirstate_map::DirstateEntryReset,
+    dirstate_tree::dirstate_map::{
+        DirstateEntryReset, DirstateIdentity as CoreDirstateIdentity,
+    },
 };
 
 use crate::{
@@ -51,10 +53,13 @@
     @staticmethod
     def new_v1(
         on_disk: PyBytes,
-        identity: Option<u64>,
+        identity: Option<DirstateIdentity>,
     ) -> PyResult<PyObject> {
         let on_disk = PyBytesDeref::new(py, on_disk);
-        let (map, parents) = OwningDirstateMap::new_v1(on_disk, identity)
+        let (map, parents) = OwningDirstateMap::new_v1(
+            on_disk,
+            identity.map(|i| *i.inner(py))
+        )
             .map_err(|e| dirstate_error(py, e))?;
         let map = Self::create_instance(py, map)?;
         let p1 = PyBytes::new(py, parents.p1.as_bytes());
@@ -70,7 +75,7 @@
         data_size: usize,
         tree_metadata: PyBytes,
         uuid: PyBytes,
-        identity: Option<u64>,
+        identity: Option<DirstateIdentity>,
     ) -> PyResult<PyObject> {
         let dirstate_error = |e: DirstateError| {
             PyErr::new::<exc::OSError, _>(py, format!("Dirstate error: {:?}", e))
@@ -82,7 +87,7 @@
             data_size,
             tree_metadata.data(py),
             uuid.to_owned(),
-            identity,
+            identity.map(|i| *i.inner(py)),
         ).map_err(dirstate_error)?;
         let map = Self::create_instance(py, map)?;
         Ok(map.into_object())
@@ -544,6 +549,41 @@
     Option<(PyBytes, PyObject)>
 );
 
+py_class!(pub class DirstateIdentity |py| {
+    data inner: CoreDirstateIdentity;
+
+    def __new__(
+        _cls,
+        mode: u32,
+        dev: u64,
+        ino: u64,
+        nlink: u64,
+        uid: u32,
+        gid: u32,
+        size: u64,
+        mtime: i64,
+        mtime_nsec: i64,
+        ctime: i64,
+        ctime_nsec: i64) -> PyResult<DirstateIdentity> {
+            Self::create_instance(
+                py,
+                CoreDirstateIdentity {
+                    mode,
+                    dev,
+                    ino,
+                    nlink,
+                    uid,
+                    gid,
+                    size,
+                    mtime,
+                    mtime_nsec,
+                    ctime,
+                    ctime_nsec
+                }
+            )
+    }
+});
+
 fn extract_node_id(py: Python, obj: &PyObject) -> PyResult<Node> {
     let bytes = obj.extract::<PyBytes>(py)?;
     match bytes.data(py).try_into() {