Show More
@@ -259,6 +259,12 b' pub struct DirstateV2Data {' | |||||
259 | pub fallback_symlink: Option<bool>, |
|
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 | impl DirstateEntry { |
|
268 | impl DirstateEntry { | |
263 | pub fn from_v2_data(v2_data: DirstateV2Data) -> Self { |
|
269 | pub fn from_v2_data(v2_data: DirstateV2Data) -> Self { | |
264 | let DirstateV2Data { |
|
270 | let DirstateV2Data { |
@@ -11,6 +11,8 b' use crate::dirstate::parsers::pack_entry' | |||||
11 | use crate::dirstate::parsers::packed_entry_size; |
|
11 | use crate::dirstate::parsers::packed_entry_size; | |
12 | use crate::dirstate::parsers::parse_dirstate_entries; |
|
12 | use crate::dirstate::parsers::parse_dirstate_entries; | |
13 | use crate::dirstate::CopyMapIter; |
|
13 | use crate::dirstate::CopyMapIter; | |
|
14 | use crate::dirstate::DirstateV2Data; | |||
|
15 | use crate::dirstate::ParentFileData; | |||
14 | use crate::dirstate::StateMapIter; |
|
16 | use crate::dirstate::StateMapIter; | |
15 | use crate::dirstate::TruncatedTimestamp; |
|
17 | use crate::dirstate::TruncatedTimestamp; | |
16 | use crate::dirstate::SIZE_FROM_OTHER_PARENT; |
|
18 | use crate::dirstate::SIZE_FROM_OTHER_PARENT; | |
@@ -606,6 +608,73 b" 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 | fn set_tracked( |
|
678 | fn set_tracked( | |
610 | &mut self, |
|
679 | &mut self, | |
611 | filename: &HgPath, |
|
680 | filename: &HgPath, | |
@@ -812,6 +881,34 b' impl OwningDirstateMap {' | |||||
812 | self.with_dmap_mut(|map| map.set_tracked(filename, old_entry_opt)) |
|
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 | pub fn remove_file( |
|
912 | pub fn remove_file( | |
816 | &mut self, |
|
913 | &mut self, | |
817 | filename: &HgPath, |
|
914 | filename: &HgPath, |
@@ -15,6 +15,7 b' use cpython::{' | |||||
15 | exc, PyBool, PyBytes, PyClone, PyDict, PyErr, PyList, PyNone, PyObject, |
|
15 | exc, PyBool, PyBytes, PyClone, PyDict, PyErr, PyList, PyNone, PyObject, | |
16 | PyResult, Python, PythonObject, ToPyObject, UnsafePyLeaked, |
|
16 | PyResult, Python, PythonObject, ToPyObject, UnsafePyLeaked, | |
17 | }; |
|
17 | }; | |
|
18 | use hg::dirstate::{ParentFileData, TruncatedTimestamp}; | |||
18 |
|
19 | |||
19 | use crate::{ |
|
20 | use crate::{ | |
20 | dirstate::copymap::{CopyMap, CopyMapItemsIterator, CopyMapKeysIterator}, |
|
21 | dirstate::copymap::{CopyMap, CopyMapItemsIterator, CopyMapKeysIterator}, | |
@@ -141,6 +142,55 b' py_class!(pub class DirstateMap |py| {' | |||||
141 | Ok(was_tracked.to_py_object(py)) |
|
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 | def removefile( |
|
194 | def removefile( | |
145 | &self, |
|
195 | &self, | |
146 | f: PyObject, |
|
196 | f: PyObject, |
General Comments 0
You need to be logged in to leave comments.
Login now