Mercurial > hg
changeset 49108:119c7e2b4248
rust-dirstatemap: add `set_untracked` method
This is the new API that Python has already migrated to
Differential Revision: https://phab.mercurial-scm.org/D12506
author | Raphaël Gomès <rgomes@octobus.net> |
---|---|
date | Mon, 28 Mar 2022 18:13:58 +0200 |
parents | 079aaf996eca |
children | 953b08a2d983 |
files | rust/hg-core/src/dirstate_tree/dirstate_map.rs rust/hg-cpython/src/dirstate/dirstate_map.rs |
diffstat | 2 files changed, 69 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/rust/hg-core/src/dirstate_tree/dirstate_map.rs Mon Mar 28 18:10:19 2022 +0200 +++ b/rust/hg-core/src/dirstate_tree/dirstate_map.rs Mon Mar 28 18:13:58 2022 +0200 @@ -772,6 +772,32 @@ Ok(()) } + /// It is the responsibility of the caller to know that there was an entry + /// there before. Does not handle the removal of copy source + fn set_untracked( + &mut self, + filename: &HgPath, + old_entry: DirstateEntry, + ) -> Result<(), DirstateV2ParseError> { + let node = Self::get_or_insert_node( + self.on_disk, + &mut self.unreachable_bytes, + &mut self.root, + filename, + WithBasename::to_cow_owned, + |ancestor| { + ancestor.tracked_descendants_count = ancestor + .tracked_descendants_count + .checked_sub(1) + .expect("tracked_descendants_count should be >= 0"); + }, + )?; + let mut new_entry = old_entry.clone(); + new_entry.set_untracked(); + node.data = NodeData::Entry(new_entry); + Ok(()) + } + fn set_clean( &mut self, filename: &HgPath, @@ -933,6 +959,39 @@ self.with_dmap_mut(|map| map.set_tracked(filename, old_entry_opt)) } + pub fn set_untracked( + &mut self, + filename: &HgPath, + ) -> Result<bool, DirstateError> { + let old_entry_opt = self.get(filename)?; + match old_entry_opt { + None => Ok(false), + Some(old_entry) => { + if !old_entry.tracked() { + // `DirstateMap::set_untracked` is not a noop if + // already not tracked as it will decrement the + // tracked counters while going down. + return Ok(true); + } + if old_entry.added() { + // Untracking an "added" entry will just result in a + // worthless entry (and other parts of the code will + // complain about it), just drop it entirely. + self.drop_entry_and_copy_source(filename)?; + return Ok(true); + } + if !old_entry.p2_info() { + self.copy_map_remove(filename)?; + } + + self.with_dmap_mut(|map| { + map.set_untracked(filename, old_entry)?; + Ok(true) + }) + } + } + } + pub fn set_clean( &mut self, filename: &HgPath,
--- a/rust/hg-cpython/src/dirstate/dirstate_map.rs Mon Mar 28 18:10:19 2022 +0200 +++ b/rust/hg-cpython/src/dirstate/dirstate_map.rs Mon Mar 28 18:13:58 2022 +0200 @@ -142,6 +142,16 @@ Ok(was_tracked.to_py_object(py)) } + def set_untracked(&self, f: PyObject) -> PyResult<PyBool> { + let bytes = f.extract::<PyBytes>(py)?; + let path = HgPath::new(bytes.data(py)); + let res = self.inner(py).borrow_mut().set_untracked(path); + let was_tracked = res.or_else(|_| { + Err(PyErr::new::<exc::OSError, _>(py, "Dirstate error".to_string())) + })?; + Ok(was_tracked.to_py_object(py)) + } + def set_clean( &self, f: PyObject,