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 @@ -427,6 +427,13 @@ _ => None, } } + + fn as_entry_mut(&mut self) -> Option<&mut DirstateEntry> { + match self { + NodeData::Entry(entry) => Some(entry), + _ => None, + } + } } impl<'on_disk> DirstateMap<'on_disk> { @@ -791,6 +798,24 @@ Ok(()) } + fn set_possibly_dirty( + &mut self, + filename: &HgPath, + ) -> 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 entry = node.data.as_entry_mut().expect("entry should exist"); + entry.set_possibly_dirty(); + node.data = NodeData::Entry(*entry); + Ok(()) + } + fn iter_nodes<'tree>( &'tree self, ) -> impl Iterator< @@ -929,6 +954,16 @@ }) } + pub fn set_possibly_dirty( + &mut self, + filename: &HgPath, + ) -> Result<(), DirstateError> { + if self.get(filename)?.is_none() { + return Err(DirstateMapError::PathNotFound(filename.into()).into()); + } + self.with_dmap_mut(|map| map.set_possibly_dirty(filename)) + } + 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 @@ -164,6 +164,16 @@ Ok(PyNone) } + def set_possibly_dirty(&self, f: PyObject) -> PyResult { + let bytes = f.extract::(py)?; + let path = HgPath::new(bytes.data(py)); + let res = self.inner(py).borrow_mut().set_possibly_dirty(path); + res.or_else(|_| { + Err(PyErr::new::(py, "Dirstate error".to_string())) + })?; + Ok(PyNone) + } + def reset_state( &self, f: PyObject,