This is the new API which has already been defined in Python
Details
Details
Diff Detail
Diff Detail
- Repository
- rHG Mercurial
- Branch
- default
- Lint
No Linters Available - Unit
No Unit Test Coverage
This is the new API which has already been defined in Python
| No Linters Available |
| No Unit Test Coverage |
| Path | Packages | |||
|---|---|---|---|---|
| M | rust/hg-core/src/dirstate/entry.rs (6 lines) | |||
| M | rust/hg-core/src/dirstate_tree/dirstate_map.rs (97 lines) | |||
| M | rust/hg-cpython/src/dirstate/dirstate_map.rs (50 lines) |
| Commit | Parents | Author | Summary | Date |
|---|---|---|---|---|
| 25d62b65116c | 6ec9e0a0e87f | Raphaël Gomès | Mar 23 2022, 12:27 PM |
| Status | Author | Revision | |
|---|---|---|---|
| Closed | Alphare | ||
| Closed | Alphare | ||
| Closed | Alphare | ||
| Closed | Alphare | ||
| Closed | Alphare | ||
| Closed | Alphare | ||
| Closed | Alphare | ||
| Closed | Alphare | ||
| Closed | Alphare | ||
| Closed | Alphare | ||
| Closed | Alphare | ||
| Closed | Alphare | ||
| Closed | Alphare | ||
| Closed | Alphare | ||
| Closed | Alphare | ||
| Closed | Alphare | ||
| Closed | Alphare | ||
| Closed | Alphare | ||
| Closed | Alphare | ||
| Closed | Alphare | ||
| Closed | Alphare | ||
| Closed | Alphare | ||
| Closed | Alphare | ||
| Closed | Alphare | ||
| Closed | Alphare | ||
| Closed | Alphare | ||
| Closed | Alphare | ||
| Closed | Alphare | ||
| Closed | Alphare | ||
| Closed | Alphare | ||
| Closed | Alphare | ||
| Closed | Alphare | ||
| Closed | Alphare | ||
| Closed | Alphare | ||
| Closed | Alphare | ||
| Closed | Alphare |
| pub p1_tracked: bool, | pub p1_tracked: bool, | ||||
| pub p2_info: bool, | pub p2_info: bool, | ||||
| pub mode_size: Option<(u32, u32)>, | pub mode_size: Option<(u32, u32)>, | ||||
| pub mtime: Option<TruncatedTimestamp>, | pub mtime: Option<TruncatedTimestamp>, | ||||
| pub fallback_exec: Option<bool>, | pub fallback_exec: Option<bool>, | ||||
| pub fallback_symlink: Option<bool>, | pub fallback_symlink: Option<bool>, | ||||
| } | } | ||||
| #[derive(Debug, Default, Copy, Clone)] | |||||
| pub struct ParentFileData { | |||||
| pub mode_size: Option<(u32, u32)>, | |||||
| pub mtime: Option<TruncatedTimestamp>, | |||||
| } | |||||
| impl DirstateEntry { | impl DirstateEntry { | ||||
| pub fn from_v2_data(v2_data: DirstateV2Data) -> Self { | pub fn from_v2_data(v2_data: DirstateV2Data) -> Self { | ||||
| let DirstateV2Data { | let DirstateV2Data { | ||||
| wc_tracked, | wc_tracked, | ||||
| p1_tracked, | p1_tracked, | ||||
| p2_info, | p2_info, | ||||
| mode_size, | mode_size, | ||||
| mtime, | mtime, | ||||
| use bytes_cast::BytesCast; | use bytes_cast::BytesCast; | ||||
| use micro_timer::timed; | use micro_timer::timed; | ||||
| use std::borrow::Cow; | use std::borrow::Cow; | ||||
| use std::path::PathBuf; | use std::path::PathBuf; | ||||
| use super::on_disk; | use super::on_disk; | ||||
| use super::on_disk::DirstateV2ParseError; | use super::on_disk::DirstateV2ParseError; | ||||
| use super::owning::OwningDirstateMap; | use super::owning::OwningDirstateMap; | ||||
| use super::path_with_basename::WithBasename; | use super::path_with_basename::WithBasename; | ||||
| use crate::dirstate::parsers::pack_entry; | use crate::dirstate::parsers::pack_entry; | ||||
| use crate::dirstate::parsers::packed_entry_size; | use crate::dirstate::parsers::packed_entry_size; | ||||
| use crate::dirstate::parsers::parse_dirstate_entries; | use crate::dirstate::parsers::parse_dirstate_entries; | ||||
| use crate::dirstate::CopyMapIter; | use crate::dirstate::CopyMapIter; | ||||
| use crate::dirstate::DirstateV2Data; | |||||
| use crate::dirstate::ParentFileData; | |||||
| use crate::dirstate::StateMapIter; | use crate::dirstate::StateMapIter; | ||||
| use crate::dirstate::TruncatedTimestamp; | use crate::dirstate::TruncatedTimestamp; | ||||
| use crate::dirstate::SIZE_FROM_OTHER_PARENT; | use crate::dirstate::SIZE_FROM_OTHER_PARENT; | ||||
| use crate::dirstate::SIZE_NON_NORMAL; | use crate::dirstate::SIZE_NON_NORMAL; | ||||
| use crate::matchers::Matcher; | use crate::matchers::Matcher; | ||||
| use crate::utils::hg_path::{HgPath, HgPathBuf}; | use crate::utils::hg_path::{HgPath, HgPathBuf}; | ||||
| use crate::DirstateEntry; | use crate::DirstateEntry; | ||||
| use crate::DirstateError; | use crate::DirstateError; | ||||
| ancestor_path = next; | ancestor_path = next; | ||||
| child_nodes = &mut child_node.children; | child_nodes = &mut child_node.children; | ||||
| } else { | } else { | ||||
| return Ok(child_node); | return Ok(child_node); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| 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( | fn set_tracked( | ||||
| &mut self, | &mut self, | ||||
| filename: &HgPath, | filename: &HgPath, | ||||
| old_entry_opt: Option<DirstateEntry>, | old_entry_opt: Option<DirstateEntry>, | ||||
| ) -> Result<bool, DirstateV2ParseError> { | ) -> Result<bool, DirstateV2ParseError> { | ||||
| let was_tracked = old_entry_opt.map_or(false, |e| e.tracked()); | let was_tracked = old_entry_opt.map_or(false, |e| e.tracked()); | ||||
| let had_entry = old_entry_opt.is_some(); | let had_entry = old_entry_opt.is_some(); | ||||
| let tracked_count_increment = if was_tracked { 0 } else { 1 }; | let tracked_count_increment = if was_tracked { 0 } else { 1 }; | ||||
| pub fn set_tracked( | pub fn set_tracked( | ||||
| &mut self, | &mut self, | ||||
| filename: &HgPath, | filename: &HgPath, | ||||
| ) -> Result<bool, DirstateV2ParseError> { | ) -> Result<bool, DirstateV2ParseError> { | ||||
| let old_entry_opt = self.get(filename)?; | let old_entry_opt = self.get(filename)?; | ||||
| self.with_dmap_mut(|map| map.set_tracked(filename, old_entry_opt)) | 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( | pub fn remove_file( | ||||
| &mut self, | &mut self, | ||||
| filename: &HgPath, | filename: &HgPath, | ||||
| in_merge: bool, | in_merge: bool, | ||||
| ) -> Result<(), DirstateError> { | ) -> Result<(), DirstateError> { | ||||
| let old_entry_opt = self.get(filename)?; | let old_entry_opt = self.get(filename)?; | ||||
| let old_state = old_entry_opt.map(|e| e.state()); | let old_state = old_entry_opt.map(|e| e.state()); | ||||
| let mut size = 0; | let mut size = 0; | ||||
| use std::cell::{RefCell, RefMut}; | use std::cell::{RefCell, RefMut}; | ||||
| use std::convert::TryInto; | use std::convert::TryInto; | ||||
| use cpython::{ | use cpython::{ | ||||
| exc, PyBool, PyBytes, PyClone, PyDict, PyErr, PyList, PyNone, PyObject, | exc, PyBool, PyBytes, PyClone, PyDict, PyErr, PyList, PyNone, PyObject, | ||||
| PyResult, Python, PythonObject, ToPyObject, UnsafePyLeaked, | PyResult, Python, PythonObject, ToPyObject, UnsafePyLeaked, | ||||
| }; | }; | ||||
| use hg::dirstate::{ParentFileData, TruncatedTimestamp}; | |||||
| use crate::{ | use crate::{ | ||||
| dirstate::copymap::{CopyMap, CopyMapItemsIterator, CopyMapKeysIterator}, | dirstate::copymap::{CopyMap, CopyMapItemsIterator, CopyMapKeysIterator}, | ||||
| dirstate::item::DirstateItem, | dirstate::item::DirstateItem, | ||||
| pybytes_deref::PyBytesDeref, | pybytes_deref::PyBytesDeref, | ||||
| }; | }; | ||||
| use hg::{ | use hg::{ | ||||
| dirstate::StateMapIter, | dirstate::StateMapIter, | ||||
| let path = HgPath::new(bytes.data(py)); | let path = HgPath::new(bytes.data(py)); | ||||
| let res = self.inner(py).borrow_mut().set_tracked(path); | let res = self.inner(py).borrow_mut().set_tracked(path); | ||||
| let was_tracked = res.or_else(|_| { | let was_tracked = res.or_else(|_| { | ||||
| Err(PyErr::new::<exc::OSError, _>(py, "Dirstate error".to_string())) | Err(PyErr::new::<exc::OSError, _>(py, "Dirstate error".to_string())) | ||||
| })?; | })?; | ||||
| Ok(was_tracked.to_py_object(py)) | Ok(was_tracked.to_py_object(py)) | ||||
| } | } | ||||
| def reset_state( | |||||
| &self, | |||||
| f: PyObject, | |||||
| wc_tracked: bool, | |||||
| p1_tracked: bool, | |||||
| p2_info: bool, | |||||
| has_meaningful_mtime: bool, | |||||
| parentfiledata: Option<(u32, u32, Option<(i64, u32, bool)>)>, | |||||
| ) -> PyResult<PyNone> { | |||||
| let mut has_meaningful_mtime = has_meaningful_mtime; | |||||
| let parent_file_data = match parentfiledata { | |||||
| None => { | |||||
| has_meaningful_mtime = false; | |||||
| None | |||||
| }, | |||||
| Some(data) => { | |||||
| let (mode, size, mtime_info) = data; | |||||
| let mtime = if let Some(mtime_info) = mtime_info { | |||||
| let (mtime_s, mtime_ns, second_ambiguous) = mtime_info; | |||||
| let timestamp = TruncatedTimestamp::new_truncate( | |||||
| mtime_s, mtime_ns, second_ambiguous | |||||
| ); | |||||
| Some(timestamp) | |||||
| } else { | |||||
| has_meaningful_mtime = false; | |||||
| None | |||||
| }; | |||||
| Some(ParentFileData { | |||||
| mode_size: Some((mode, size)), | |||||
| mtime, | |||||
| }) | |||||
| } | |||||
| }; | |||||
| let bytes = f.extract::<PyBytes>(py)?; | |||||
| let path = HgPath::new(bytes.data(py)); | |||||
| let res = self.inner(py).borrow_mut().reset_state( | |||||
| path, | |||||
| wc_tracked, | |||||
| p1_tracked, | |||||
| p2_info, | |||||
| has_meaningful_mtime, | |||||
| parent_file_data, | |||||
| ); | |||||
| res.or_else(|_| { | |||||
| Err(PyErr::new::<exc::OSError, _>(py, "Dirstate error".to_string())) | |||||
| })?; | |||||
| Ok(PyNone) | |||||
| } | |||||
| def removefile( | def removefile( | ||||
| &self, | &self, | ||||
| f: PyObject, | f: PyObject, | ||||
| in_merge: PyObject | in_merge: PyObject | ||||
| ) -> PyResult<PyObject> { | ) -> PyResult<PyObject> { | ||||
| self.inner(py).borrow_mut() | self.inner(py).borrow_mut() | ||||
| .remove_file( | .remove_file( | ||||
| HgPath::new(f.extract::<PyBytes>(py)?.data(py)), | HgPath::new(f.extract::<PyBytes>(py)?.data(py)), | ||||