Show More
@@ -259,6 +259,12 pub struct DirstateV2Data { | |||
|
259 | 259 | pub fallback_symlink: Option<bool>, |
|
260 | 260 | } |
|
261 | 261 | |
|
262 | #[derive(Debug, Default, Copy, Clone)] | |
|
263 | pub struct ParentFileData { | |
|
264 | pub mode_size: Option<(u32, u32)>, | |
|
265 | pub mtime: Option<TruncatedTimestamp>, | |
|
266 | } | |
|
267 | ||
|
262 | 268 | impl DirstateEntry { |
|
263 | 269 | pub fn from_v2_data(v2_data: DirstateV2Data) -> Self { |
|
264 | 270 | let DirstateV2Data { |
@@ -11,6 +11,8 use crate::dirstate::parsers::pack_entry | |||
|
11 | 11 | use crate::dirstate::parsers::packed_entry_size; |
|
12 | 12 | use crate::dirstate::parsers::parse_dirstate_entries; |
|
13 | 13 | use crate::dirstate::CopyMapIter; |
|
14 | use crate::dirstate::DirstateV2Data; | |
|
15 | use crate::dirstate::ParentFileData; | |
|
14 | 16 | use crate::dirstate::StateMapIter; |
|
15 | 17 | use crate::dirstate::TruncatedTimestamp; |
|
16 | 18 | use crate::dirstate::SIZE_FROM_OTHER_PARENT; |
@@ -606,6 +608,73 impl<'on_disk> DirstateMap<'on_disk> { | |||
|
606 | 608 | } |
|
607 | 609 | } |
|
608 | 610 | |
|
611 | fn reset_state( | |
|
612 | &mut self, | |
|
613 | filename: &HgPath, | |
|
614 | old_entry_opt: Option<DirstateEntry>, | |
|
615 | wc_tracked: bool, | |
|
616 | p1_tracked: bool, | |
|
617 | p2_info: bool, | |
|
618 | has_meaningful_mtime: bool, | |
|
619 | parent_file_data_opt: Option<ParentFileData>, | |
|
620 | ) -> Result<(), DirstateError> { | |
|
621 | let (had_entry, was_tracked) = match old_entry_opt { | |
|
622 | Some(old_entry) => (true, old_entry.tracked()), | |
|
623 | None => (false, false), | |
|
624 | }; | |
|
625 | let node = Self::get_or_insert_node( | |
|
626 | self.on_disk, | |
|
627 | &mut self.unreachable_bytes, | |
|
628 | &mut self.root, | |
|
629 | filename, | |
|
630 | WithBasename::to_cow_owned, | |
|
631 | |ancestor| { | |
|
632 | if !had_entry { | |
|
633 | ancestor.descendants_with_entry_count += 1; | |
|
634 | } | |
|
635 | if was_tracked { | |
|
636 | if !wc_tracked { | |
|
637 | ancestor.tracked_descendants_count = ancestor | |
|
638 | .tracked_descendants_count | |
|
639 | .checked_sub(1) | |
|
640 | .expect("tracked count to be >= 0"); | |
|
641 | } | |
|
642 | } else { | |
|
643 | if wc_tracked { | |
|
644 | ancestor.tracked_descendants_count += 1; | |
|
645 | } | |
|
646 | } | |
|
647 | }, | |
|
648 | )?; | |
|
649 | ||
|
650 | let v2_data = if let Some(parent_file_data) = parent_file_data_opt { | |
|
651 | DirstateV2Data { | |
|
652 | wc_tracked, | |
|
653 | p1_tracked, | |
|
654 | p2_info, | |
|
655 | mode_size: parent_file_data.mode_size, | |
|
656 | mtime: if has_meaningful_mtime { | |
|
657 | parent_file_data.mtime | |
|
658 | } else { | |
|
659 | None | |
|
660 | }, | |
|
661 | ..Default::default() | |
|
662 | } | |
|
663 | } else { | |
|
664 | DirstateV2Data { | |
|
665 | wc_tracked, | |
|
666 | p1_tracked, | |
|
667 | p2_info, | |
|
668 | ..Default::default() | |
|
669 | } | |
|
670 | }; | |
|
671 | if !had_entry { | |
|
672 | self.nodes_with_entry_count += 1; | |
|
673 | } | |
|
674 | node.data = NodeData::Entry(DirstateEntry::from_v2_data(v2_data)); | |
|
675 | Ok(()) | |
|
676 | } | |
|
677 | ||
|
609 | 678 | fn set_tracked( |
|
610 | 679 | &mut self, |
|
611 | 680 | filename: &HgPath, |
@@ -812,6 +881,34 impl OwningDirstateMap { | |||
|
812 | 881 | self.with_dmap_mut(|map| map.set_tracked(filename, old_entry_opt)) |
|
813 | 882 | } |
|
814 | 883 | |
|
884 | pub fn reset_state( | |
|
885 | &mut self, | |
|
886 | filename: &HgPath, | |
|
887 | wc_tracked: bool, | |
|
888 | p1_tracked: bool, | |
|
889 | p2_info: bool, | |
|
890 | has_meaningful_mtime: bool, | |
|
891 | parent_file_data_opt: Option<ParentFileData>, | |
|
892 | ) -> Result<(), DirstateError> { | |
|
893 | if !(p1_tracked || p2_info || wc_tracked) { | |
|
894 | self.drop_entry_and_copy_source(filename)?; | |
|
895 | return Ok(()); | |
|
896 | } | |
|
897 | self.copy_map_remove(filename)?; | |
|
898 | let old_entry_opt = self.get(filename)?; | |
|
899 | self.with_dmap_mut(|map| { | |
|
900 | map.reset_state( | |
|
901 | filename, | |
|
902 | old_entry_opt, | |
|
903 | wc_tracked, | |
|
904 | p1_tracked, | |
|
905 | p2_info, | |
|
906 | has_meaningful_mtime, | |
|
907 | parent_file_data_opt, | |
|
908 | ) | |
|
909 | }) | |
|
910 | } | |
|
911 | ||
|
815 | 912 | pub fn remove_file( |
|
816 | 913 | &mut self, |
|
817 | 914 | filename: &HgPath, |
@@ -15,6 +15,7 use cpython::{ | |||
|
15 | 15 | exc, PyBool, PyBytes, PyClone, PyDict, PyErr, PyList, PyNone, PyObject, |
|
16 | 16 | PyResult, Python, PythonObject, ToPyObject, UnsafePyLeaked, |
|
17 | 17 | }; |
|
18 | use hg::dirstate::{ParentFileData, TruncatedTimestamp}; | |
|
18 | 19 | |
|
19 | 20 | use crate::{ |
|
20 | 21 | dirstate::copymap::{CopyMap, CopyMapItemsIterator, CopyMapKeysIterator}, |
@@ -141,6 +142,55 py_class!(pub class DirstateMap |py| { | |||
|
141 | 142 | Ok(was_tracked.to_py_object(py)) |
|
142 | 143 | } |
|
143 | 144 | |
|
145 | def reset_state( | |
|
146 | &self, | |
|
147 | f: PyObject, | |
|
148 | wc_tracked: bool, | |
|
149 | p1_tracked: bool, | |
|
150 | p2_info: bool, | |
|
151 | has_meaningful_mtime: bool, | |
|
152 | parentfiledata: Option<(u32, u32, Option<(i64, u32, bool)>)>, | |
|
153 | ) -> PyResult<PyNone> { | |
|
154 | let mut has_meaningful_mtime = has_meaningful_mtime; | |
|
155 | let parent_file_data = match parentfiledata { | |
|
156 | None => { | |
|
157 | has_meaningful_mtime = false; | |
|
158 | None | |
|
159 | }, | |
|
160 | Some(data) => { | |
|
161 | let (mode, size, mtime_info) = data; | |
|
162 | let mtime = if let Some(mtime_info) = mtime_info { | |
|
163 | let (mtime_s, mtime_ns, second_ambiguous) = mtime_info; | |
|
164 | let timestamp = TruncatedTimestamp::new_truncate( | |
|
165 | mtime_s, mtime_ns, second_ambiguous | |
|
166 | ); | |
|
167 | Some(timestamp) | |
|
168 | } else { | |
|
169 | has_meaningful_mtime = false; | |
|
170 | None | |
|
171 | }; | |
|
172 | Some(ParentFileData { | |
|
173 | mode_size: Some((mode, size)), | |
|
174 | mtime, | |
|
175 | }) | |
|
176 | } | |
|
177 | }; | |
|
178 | let bytes = f.extract::<PyBytes>(py)?; | |
|
179 | let path = HgPath::new(bytes.data(py)); | |
|
180 | let res = self.inner(py).borrow_mut().reset_state( | |
|
181 | path, | |
|
182 | wc_tracked, | |
|
183 | p1_tracked, | |
|
184 | p2_info, | |
|
185 | has_meaningful_mtime, | |
|
186 | parent_file_data, | |
|
187 | ); | |
|
188 | res.or_else(|_| { | |
|
189 | Err(PyErr::new::<exc::OSError, _>(py, "Dirstate error".to_string())) | |
|
190 | })?; | |
|
191 | Ok(PyNone) | |
|
192 | } | |
|
193 | ||
|
144 | 194 | def removefile( |
|
145 | 195 | &self, |
|
146 | 196 | f: PyObject, |
General Comments 0
You need to be logged in to leave comments.
Login now