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 @@ -21,6 +21,7 @@ use crate::utils::hg_path::{HgPath, HgPathBuf}; use crate::DirstateEntry; use crate::DirstateError; +use crate::DirstateMapError; use crate::DirstateParents; use crate::DirstateStatus; use crate::EntryState; @@ -765,6 +766,28 @@ Ok(()) } + fn set_clean( + &mut self, + filename: &HgPath, + old_entry: DirstateEntry, + mode: u32, + size: u32, + mtime: TruncatedTimestamp, + ) -> Result<(), DirstateError> { + let node = Self::get_or_insert_node( + self.on_disk, + &mut self.unreachable_bytes, + &mut self.root, + filename, + WithBasename::to_cow_owned, + |_ancestor| {}, + )?; + let mut new_entry = old_entry.clone(); + new_entry.set_clean(mode, size, mtime); + node.data = NodeData::Entry(new_entry); + Ok(()) + } + fn iter_nodes<'tree>( &'tree self, ) -> impl Iterator< @@ -882,6 +905,27 @@ self.with_dmap_mut(|map| map.set_tracked(filename, old_entry_opt)) } + pub fn set_clean( + &mut self, + filename: &HgPath, + mode: u32, + size: u32, + mtime: TruncatedTimestamp, + ) -> Result<(), DirstateError> { + let old_entry = match self.get(filename)? { + None => { + return Err( + DirstateMapError::PathNotFound(filename.into()).into() + ) + } + Some(e) => e, + }; + self.copy_map_remove(filename)?; + self.with_dmap_mut(|map| { + map.set_clean(filename, old_entry, mode, size, mtime) + }) + } + pub fn reset_state( &mut self, filename: &HgPath, 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 @@ -145,6 +145,33 @@ })?.to_py_object(py)) } + def set_clean( + &self, + f: PyObject, + mode: u32, + size: u32, + mtime: (i64, u32, bool) + ) -> PyResult { + let (mtime_s, mtime_ns, second_ambiguous) = mtime; + let timestamp = TruncatedTimestamp::new_truncate( + mtime_s, mtime_ns, second_ambiguous + ); + self.inner(py).borrow_mut() + .set_clean( + HgPath::new(f.extract::(py)?.data(py)), + mode, + size, + timestamp, + ) + .or_else(|_| { + Err(PyErr::new::( + py, + "Dirstate error".to_string(), + )) + })?; + Ok(PyNone) + } + def reset_state( &self, f: PyObject,