--- a/rust/hg-core/src/dirstate_tree/dirstate_map.rs Wed Mar 23 17:38:59 2022 +0100
+++ b/rust/hg-core/src/dirstate_tree/dirstate_map.rs Wed Mar 23 17:27:58 2022 +0100
@@ -11,6 +11,8 @@
use crate::dirstate::parsers::packed_entry_size;
use crate::dirstate::parsers::parse_dirstate_entries;
use crate::dirstate::CopyMapIter;
+use crate::dirstate::DirstateV2Data;
+use crate::dirstate::ParentFileData;
use crate::dirstate::StateMapIter;
use crate::dirstate::TruncatedTimestamp;
use crate::dirstate::SIZE_FROM_OTHER_PARENT;
@@ -606,6 +608,73 @@
}
}
+ fn reset_state(
+ &mut self,
+ filename: &HgPath,
+ old_entry_opt: Option<DirstateEntry>,
+ wc_tracked: bool,
+ p1_tracked: bool,
+ p2_info: bool,
+ has_meaningful_mtime: bool,
+ parent_file_data_opt: Option<ParentFileData>,
+ ) -> Result<(), DirstateError> {
+ let (had_entry, was_tracked) = match old_entry_opt {
+ Some(old_entry) => (true, old_entry.tracked()),
+ None => (false, false),
+ };
+ let node = Self::get_or_insert_node(
+ self.on_disk,
+ &mut self.unreachable_bytes,
+ &mut self.root,
+ filename,
+ WithBasename::to_cow_owned,
+ |ancestor| {
+ if !had_entry {
+ ancestor.descendants_with_entry_count += 1;
+ }
+ if was_tracked {
+ if !wc_tracked {
+ ancestor.tracked_descendants_count = ancestor
+ .tracked_descendants_count
+ .checked_sub(1)
+ .expect("tracked count to be >= 0");
+ }
+ } else {
+ if wc_tracked {
+ ancestor.tracked_descendants_count += 1;
+ }
+ }
+ },
+ )?;
+
+ let v2_data = if let Some(parent_file_data) = parent_file_data_opt {
+ DirstateV2Data {
+ wc_tracked,
+ p1_tracked,
+ p2_info,
+ mode_size: parent_file_data.mode_size,
+ mtime: if has_meaningful_mtime {
+ parent_file_data.mtime
+ } else {
+ None
+ },
+ ..Default::default()
+ }
+ } else {
+ DirstateV2Data {
+ wc_tracked,
+ p1_tracked,
+ p2_info,
+ ..Default::default()
+ }
+ };
+ if !had_entry {
+ self.nodes_with_entry_count += 1;
+ }
+ node.data = NodeData::Entry(DirstateEntry::from_v2_data(v2_data));
+ Ok(())
+ }
+
fn set_tracked(
&mut self,
filename: &HgPath,
@@ -812,6 +881,34 @@
self.with_dmap_mut(|map| map.set_tracked(filename, old_entry_opt))
}
+ pub fn reset_state(
+ &mut self,
+ filename: &HgPath,
+ wc_tracked: bool,
+ p1_tracked: bool,
+ p2_info: bool,
+ has_meaningful_mtime: bool,
+ parent_file_data_opt: Option<ParentFileData>,
+ ) -> Result<(), DirstateError> {
+ if !(p1_tracked || p2_info || wc_tracked) {
+ self.drop_entry_and_copy_source(filename)?;
+ return Ok(());
+ }
+ self.copy_map_remove(filename)?;
+ let old_entry_opt = self.get(filename)?;
+ self.with_dmap_mut(|map| {
+ map.reset_state(
+ filename,
+ old_entry_opt,
+ wc_tracked,
+ p1_tracked,
+ p2_info,
+ has_meaningful_mtime,
+ parent_file_data_opt,
+ )
+ })
+ }
+
pub fn remove_file(
&mut self,
filename: &HgPath,