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 |
---|---|---|---|---|
7b81a6c2fcc4 | a7d21c331f1b | 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)), |