Now that the Python DirstateItem class wraps a Rust DirstateEntry value,
use that value directly instead of converting through v1 data + 5 booleans.
Also remove propogating the return value. None of the callers look at it,
and it is always None.
| Alphare |
| hg-reviewers |
Now that the Python DirstateItem class wraps a Rust DirstateEntry value,
use that value directly instead of converting through v1 data + 5 booleans.
Also remove propogating the return value. None of the callers look at it,
and it is always None.
| Automatic diff as part of commit; lint not applicable. |
| Automatic diff as part of commit; unit tests not applicable. |
| Path | Packages | |||
|---|---|---|---|---|
| M | mercurial/dirstatemap.py (29 lines) | |||
| M | rust/hg-core/src/dirstate/dirstate_map.rs (43 lines) | |||
| M | rust/hg-core/src/dirstate/entry.rs (32 lines) | |||
| M | rust/hg-core/src/dirstate_tree/dirstate_map.rs (39 lines) | |||
| M | rust/hg-core/src/dirstate_tree/dispatch.rs (10 lines) | |||
| M | rust/hg-core/src/dirstate_tree/owning_dispatch.rs (13 lines) | |||
| M | rust/hg-cpython/src/dirstate/dirstate_map.rs (54 lines) | |||
| M | rust/hg-cpython/src/dirstate/item.rs (30 lines) |
| Status | Author | Revision | |
|---|---|---|---|
| Closed | SimonSapin | ||
| Closed | SimonSapin | ||
| Closed | SimonSapin | ||
| Closed | SimonSapin | ||
| Closed | SimonSapin | ||
| Closed | SimonSapin | ||
| Closed | SimonSapin | ||
| Closed | SimonSapin | ||
| Closed | SimonSapin | ||
| Closed | SimonSapin |
| mode=0, | mode=0, | ||||
| size=None, | size=None, | ||||
| mtime=None, | mtime=None, | ||||
| added=False, | added=False, | ||||
| merged=False, | merged=False, | ||||
| from_p2=False, | from_p2=False, | ||||
| possibly_dirty=False, | possibly_dirty=False, | ||||
| ): | ): | ||||
| ret = self._rustmap.addfile( | if added: | ||||
| f, | assert not possibly_dirty | ||||
| mode, | assert not from_p2 | ||||
| size, | item = DirstateItem.new_added() | ||||
| mtime, | elif merged: | ||||
| added, | assert not possibly_dirty | ||||
| merged, | assert not from_p2 | ||||
| from_p2, | item = DirstateItem.new_merged() | ||||
| possibly_dirty, | elif from_p2: | ||||
| ) | assert not possibly_dirty | ||||
| item = DirstateItem.new_from_p2() | |||||
| elif possibly_dirty: | |||||
| item = DirstateItem.new_possibly_dirty() | |||||
| else: | |||||
| size = size & rangemask | |||||
| mtime = mtime & rangemask | |||||
| item = DirstateItem.new_normal(mode, size, mtime) | |||||
| self._rustmap.addfile(f, item) | |||||
| if added: | if added: | ||||
| self.copymap.pop(f, None) | self.copymap.pop(f, None) | ||||
| return ret | |||||
| def reset_state( | def reset_state( | ||||
| self, | self, | ||||
| filename, | filename, | ||||
| wc_tracked=False, | wc_tracked=False, | ||||
| p1_tracked=False, | p1_tracked=False, | ||||
| p2_tracked=False, | p2_tracked=False, | ||||
| merged=False, | merged=False, | ||||
| // dirstate_map.rs | // dirstate_map.rs | ||||
| // | // | ||||
| // Copyright 2019 Raphaël Gomès <rgomes@octobus.net> | // Copyright 2019 Raphaël Gomès <rgomes@octobus.net> | ||||
| // | // | ||||
| // This software may be used and distributed according to the terms of the | // This software may be used and distributed according to the terms of the | ||||
| // GNU General Public License version 2 or any later version. | // GNU General Public License version 2 or any later version. | ||||
| use crate::dirstate::parsers::Timestamp; | use crate::dirstate::parsers::Timestamp; | ||||
| use crate::{ | use crate::{ | ||||
| dirstate::EntryState, | dirstate::EntryState, | ||||
| dirstate::MTIME_UNSET, | |||||
| dirstate::SIZE_FROM_OTHER_PARENT, | dirstate::SIZE_FROM_OTHER_PARENT, | ||||
| dirstate::SIZE_NON_NORMAL, | dirstate::SIZE_NON_NORMAL, | ||||
| dirstate::V1_RANGEMASK, | |||||
| pack_dirstate, parse_dirstate, | pack_dirstate, parse_dirstate, | ||||
| utils::hg_path::{HgPath, HgPathBuf}, | utils::hg_path::{HgPath, HgPathBuf}, | ||||
| CopyMap, DirsMultiset, DirstateEntry, DirstateError, DirstateParents, | CopyMap, DirsMultiset, DirstateEntry, DirstateError, DirstateParents, | ||||
| StateMap, | StateMap, | ||||
| }; | }; | ||||
| use micro_timer::timed; | use micro_timer::timed; | ||||
| use std::collections::HashSet; | use std::collections::HashSet; | ||||
| use std::iter::FromIterator; | use std::iter::FromIterator; | ||||
| self.state_map.insert(filename.to_owned(), entry); | self.state_map.insert(filename.to_owned(), entry); | ||||
| } | } | ||||
| /// Add a tracked file to the dirstate | /// Add a tracked file to the dirstate | ||||
| pub fn add_file( | pub fn add_file( | ||||
| &mut self, | &mut self, | ||||
| filename: &HgPath, | filename: &HgPath, | ||||
| entry: DirstateEntry, | entry: DirstateEntry, | ||||
| // XXX once the dust settle this should probably become an enum | |||||
| added: bool, | |||||
| merged: bool, | |||||
| from_p2: bool, | |||||
| possibly_dirty: bool, | |||||
| ) -> Result<(), DirstateError> { | ) -> Result<(), DirstateError> { | ||||
| let state; | |||||
| let size; | |||||
| let mtime; | |||||
| if added { | |||||
| assert!(!possibly_dirty); | |||||
| assert!(!from_p2); | |||||
| state = EntryState::Added; | |||||
| size = SIZE_NON_NORMAL; | |||||
| mtime = MTIME_UNSET; | |||||
| } else if merged { | |||||
| assert!(!possibly_dirty); | |||||
| assert!(!from_p2); | |||||
| state = EntryState::Merged; | |||||
| size = SIZE_FROM_OTHER_PARENT; | |||||
| mtime = MTIME_UNSET; | |||||
| } else if from_p2 { | |||||
| assert!(!possibly_dirty); | |||||
| state = EntryState::Normal; | |||||
| size = SIZE_FROM_OTHER_PARENT; | |||||
| mtime = MTIME_UNSET; | |||||
| } else if possibly_dirty { | |||||
| state = EntryState::Normal; | |||||
| size = SIZE_NON_NORMAL; | |||||
| mtime = MTIME_UNSET; | |||||
| } else { | |||||
| state = EntryState::Normal; | |||||
| size = entry.size() & V1_RANGEMASK; | |||||
| mtime = entry.mtime() & V1_RANGEMASK; | |||||
| } | |||||
| let mode = entry.mode(); | |||||
| let entry = DirstateEntry::from_v1_data(state, mode, size, mtime); | |||||
| let old_state = self.get(filename).map(|e| e.state()); | let old_state = self.get(filename).map(|e| e.state()); | ||||
| if old_state.is_none() || old_state == Some(EntryState::Removed) { | if old_state.is_none() || old_state == Some(EntryState::Removed) { | ||||
| if let Some(ref mut dirs) = self.dirs { | if let Some(ref mut dirs) = self.dirs { | ||||
| dirs.add_path(filename)?; | dirs.add_path(filename)?; | ||||
| } | } | ||||
| } | } | ||||
| if old_state.is_none() { | if old_state.is_none() { | ||||
| if let Some(ref mut all_dirs) = self.all_dirs { | if let Some(ref mut all_dirs) = self.all_dirs { | ||||
| fn test_add_file() { | fn test_add_file() { | ||||
| let mut map = DirstateMap::new(); | let mut map = DirstateMap::new(); | ||||
| assert_eq!(0, map.len()); | assert_eq!(0, map.len()); | ||||
| map.add_file( | map.add_file( | ||||
| HgPath::new(b"meh"), | HgPath::new(b"meh"), | ||||
| DirstateEntry::from_v1_data(EntryState::Normal, 1337, 1337, 1337), | DirstateEntry::from_v1_data(EntryState::Normal, 1337, 1337, 1337), | ||||
| false, | |||||
| false, | |||||
| false, | |||||
| false, | |||||
| ) | ) | ||||
| .unwrap(); | .unwrap(); | ||||
| assert_eq!(1, map.len()); | assert_eq!(1, map.len()); | ||||
| assert_eq!(0, map.get_non_normal_other_parent_entries().0.len()); | assert_eq!(0, map.get_non_normal_other_parent_entries().0.len()); | ||||
| assert_eq!(0, map.get_non_normal_other_parent_entries().1.len()); | assert_eq!(0, map.get_non_normal_other_parent_entries().1.len()); | ||||
| } | } | ||||
| flags: Flags::WDIR_TRACKED | flags: Flags::WDIR_TRACKED | ||||
| | Flags::P1_TRACKED | | Flags::P1_TRACKED | ||||
| | Flags::POSSIBLY_DIRTY, | | Flags::POSSIBLY_DIRTY, | ||||
| mode, | mode, | ||||
| size, | size, | ||||
| mtime: 0, | mtime: 0, | ||||
| } | } | ||||
| } else { | } else { | ||||
| Self { | Self::new_normal(mode, size, mtime) | ||||
| flags: Flags::WDIR_TRACKED | Flags::P1_TRACKED, | |||||
| mode, | |||||
| size, | |||||
| mtime, | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| EntryState::Added => Self::new_added(), | EntryState::Added => Self::new_added(), | ||||
| EntryState::Removed => Self { | EntryState::Removed => Self { | ||||
| flags: if size == SIZE_NON_NORMAL { | flags: if size == SIZE_NON_NORMAL { | ||||
| Flags::P1_TRACKED // might not be true because of rename ? | Flags::P1_TRACKED // might not be true because of rename ? | ||||
| | Flags::P2_TRACKED // might not be true because of rename ? | | Flags::P2_TRACKED // might not be true because of rename ? | ||||
| | Flags::MERGED | | Flags::MERGED | ||||
| } else if size == SIZE_FROM_OTHER_PARENT { | } else if size == SIZE_FROM_OTHER_PARENT { | ||||
| // We don’t know if P1_TRACKED should be set (file history) | // We don’t know if P1_TRACKED should be set (file history) | ||||
| Flags::P2_TRACKED | Flags::CLEAN_P2 | Flags::P2_TRACKED | Flags::CLEAN_P2 | ||||
| } else { | } else { | ||||
| Flags::P1_TRACKED | Flags::P1_TRACKED | ||||
| }, | }, | ||||
| mode: 0, | mode: 0, | ||||
| size: 0, | size: 0, | ||||
| mtime: 0, | mtime: 0, | ||||
| }, | }, | ||||
| EntryState::Merged => Self::new_merged(), | EntryState::Merged => Self::new_merged(), | ||||
| } | } | ||||
| } | } | ||||
| fn new_from_p2() -> Self { | pub fn new_from_p2() -> Self { | ||||
| Self { | Self { | ||||
| // might be missing P1_TRACKED | // might be missing P1_TRACKED | ||||
| flags: Flags::WDIR_TRACKED | Flags::P2_TRACKED | Flags::CLEAN_P2, | flags: Flags::WDIR_TRACKED | Flags::P2_TRACKED | Flags::CLEAN_P2, | ||||
| mode: 0, | mode: 0, | ||||
| size: SIZE_FROM_OTHER_PARENT, | size: SIZE_FROM_OTHER_PARENT, | ||||
| mtime: MTIME_UNSET, | mtime: MTIME_UNSET, | ||||
| } | } | ||||
| } | } | ||||
| fn new_possibly_dirty() -> Self { | pub fn new_possibly_dirty() -> Self { | ||||
| Self { | Self { | ||||
| flags: Flags::WDIR_TRACKED | flags: Flags::WDIR_TRACKED | ||||
| | Flags::P1_TRACKED | | Flags::P1_TRACKED | ||||
| | Flags::POSSIBLY_DIRTY, | | Flags::POSSIBLY_DIRTY, | ||||
| mode: 0, | mode: 0, | ||||
| size: SIZE_NON_NORMAL, | size: SIZE_NON_NORMAL, | ||||
| mtime: MTIME_UNSET, | mtime: MTIME_UNSET, | ||||
| } | } | ||||
| } | } | ||||
| fn new_added() -> Self { | pub fn new_added() -> Self { | ||||
| Self { | Self { | ||||
| flags: Flags::WDIR_TRACKED, | flags: Flags::WDIR_TRACKED, | ||||
| mode: 0, | mode: 0, | ||||
| size: SIZE_NON_NORMAL, | size: SIZE_NON_NORMAL, | ||||
| mtime: MTIME_UNSET, | mtime: MTIME_UNSET, | ||||
| } | } | ||||
| } | } | ||||
| fn new_merged() -> Self { | pub fn new_merged() -> Self { | ||||
| Self { | Self { | ||||
| flags: Flags::WDIR_TRACKED | flags: Flags::WDIR_TRACKED | ||||
| | Flags::P1_TRACKED // might not be true because of rename ? | | Flags::P1_TRACKED // might not be true because of rename ? | ||||
| | Flags::P2_TRACKED // might not be true because of rename ? | | Flags::P2_TRACKED // might not be true because of rename ? | ||||
| | Flags::MERGED, | | Flags::MERGED, | ||||
| mode: 0, | mode: 0, | ||||
| size: SIZE_NON_NORMAL, | size: SIZE_NON_NORMAL, | ||||
| mtime: MTIME_UNSET, | mtime: MTIME_UNSET, | ||||
| } | } | ||||
| } | } | ||||
| pub fn new_normal(mode: i32, size: i32, mtime: i32) -> Self { | |||||
| Self { | |||||
| flags: Flags::WDIR_TRACKED | Flags::P1_TRACKED, | |||||
| mode, | |||||
| size, | |||||
| mtime, | |||||
| } | |||||
| } | |||||
| /// Creates a new entry in "removed" state. | /// Creates a new entry in "removed" state. | ||||
| /// | /// | ||||
| /// `size` is expected to be zero, `SIZE_NON_NORMAL`, or | /// `size` is expected to be zero, `SIZE_NON_NORMAL`, or | ||||
| /// `SIZE_FROM_OTHER_PARENT` | /// `SIZE_FROM_OTHER_PARENT` | ||||
| pub fn new_removed(size: i32) -> Self { | pub fn new_removed(size: i32) -> Self { | ||||
| Self::from_v1_data(EntryState::Removed, 0, size, 0) | Self::from_v1_data(EntryState::Removed, 0, size, 0) | ||||
| } | } | ||||
| /// TODO: refactor `DirstateMap::add_file` to not take a `DirstateEntry` | |||||
| /// parameter and remove this constructor | |||||
| pub fn new_for_add_file(mode: i32, size: i32, mtime: i32) -> Self { | |||||
| // XXX Arbitrary default value since the value is determined later | |||||
| let state = EntryState::Normal; | |||||
| Self::from_v1_data(state, mode, size, mtime) | |||||
| } | |||||
| pub fn tracked(&self) -> bool { | pub fn tracked(&self) -> bool { | ||||
| self.flags.contains(Flags::WDIR_TRACKED) | self.flags.contains(Flags::WDIR_TRACKED) | ||||
| } | } | ||||
| fn tracked_in_any_parent(&self) -> bool { | fn tracked_in_any_parent(&self) -> bool { | ||||
| self.flags.intersects(Flags::P1_TRACKED | Flags::P2_TRACKED) | self.flags.intersects(Flags::P1_TRACKED | Flags::P2_TRACKED) | ||||
| } | } | ||||
| 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::convert::TryInto; | use std::convert::TryInto; | ||||
| 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::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::parsers::Timestamp; | use crate::dirstate::parsers::Timestamp; | ||||
| use crate::dirstate::MTIME_UNSET; | |||||
| 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::dirstate::V1_RANGEMASK; | |||||
| use crate::matchers::Matcher; | use crate::matchers::Matcher; | ||||
| use crate::utils::hg_path::{HgPath, HgPathBuf}; | use crate::utils::hg_path::{HgPath, HgPathBuf}; | ||||
| use crate::CopyMapIter; | use crate::CopyMapIter; | ||||
| use crate::DirstateEntry; | use crate::DirstateEntry; | ||||
| use crate::DirstateError; | use crate::DirstateError; | ||||
| use crate::DirstateParents; | use crate::DirstateParents; | ||||
| use crate::DirstateStatus; | use crate::DirstateStatus; | ||||
| use crate::EntryState; | use crate::EntryState; | ||||
| self.get_or_insert(&filename)?.data = NodeData::Entry(entry); | self.get_or_insert(&filename)?.data = NodeData::Entry(entry); | ||||
| Ok(()) | Ok(()) | ||||
| } | } | ||||
| fn add_file( | fn add_file( | ||||
| &mut self, | &mut self, | ||||
| filename: &HgPath, | filename: &HgPath, | ||||
| entry: DirstateEntry, | entry: DirstateEntry, | ||||
| added: bool, | |||||
| merged: bool, | |||||
| from_p2: bool, | |||||
| possibly_dirty: bool, | |||||
| ) -> Result<(), DirstateError> { | ) -> Result<(), DirstateError> { | ||||
| let state; | |||||
| let size; | |||||
| let mtime; | |||||
| if added { | |||||
| assert!(!possibly_dirty); | |||||
| assert!(!from_p2); | |||||
| state = EntryState::Added; | |||||
| size = SIZE_NON_NORMAL; | |||||
| mtime = MTIME_UNSET; | |||||
| } else if merged { | |||||
| assert!(!possibly_dirty); | |||||
| assert!(!from_p2); | |||||
| state = EntryState::Merged; | |||||
| size = SIZE_FROM_OTHER_PARENT; | |||||
| mtime = MTIME_UNSET; | |||||
| } else if from_p2 { | |||||
| assert!(!possibly_dirty); | |||||
| state = EntryState::Normal; | |||||
| size = SIZE_FROM_OTHER_PARENT; | |||||
| mtime = MTIME_UNSET; | |||||
| } else if possibly_dirty { | |||||
| state = EntryState::Normal; | |||||
| size = SIZE_NON_NORMAL; | |||||
| mtime = MTIME_UNSET; | |||||
| } else { | |||||
| state = EntryState::Normal; | |||||
| size = entry.size() & V1_RANGEMASK; | |||||
| mtime = entry.mtime() & V1_RANGEMASK; | |||||
| } | |||||
| let mode = entry.mode(); | |||||
| let entry = DirstateEntry::from_v1_data(state, mode, size, mtime); | |||||
| let old_state = self.get(filename)?.map(|e| e.state()); | let old_state = self.get(filename)?.map(|e| e.state()); | ||||
| Ok(self.add_or_remove_file(filename, old_state, entry)?) | Ok(self.add_or_remove_file(filename, old_state, entry)?) | ||||
| } | } | ||||
| fn remove_file( | fn remove_file( | ||||
| &mut self, | &mut self, | ||||
| filename: &HgPath, | filename: &HgPath, | ||||
| in_merge: bool, | in_merge: bool, | ||||
| ) -> Result<(), DirstateError> { | ) -> Result<(), DirstateError> { | ||||
| entry: DirstateEntry, | entry: DirstateEntry, | ||||
| ) -> Result<(), DirstateV2ParseError>; | ) -> Result<(), DirstateV2ParseError>; | ||||
| /// Add or change the information associated to a given file. | /// Add or change the information associated to a given file. | ||||
| fn add_file( | fn add_file( | ||||
| &mut self, | &mut self, | ||||
| filename: &HgPath, | filename: &HgPath, | ||||
| entry: DirstateEntry, | entry: DirstateEntry, | ||||
| added: bool, | |||||
| merged: bool, | |||||
| from_p2: bool, | |||||
| possibly_dirty: bool, | |||||
| ) -> Result<(), DirstateError>; | ) -> Result<(), DirstateError>; | ||||
| /// Mark a file as "removed" (as in `hg rm`). | /// Mark a file as "removed" (as in `hg rm`). | ||||
| fn remove_file( | fn remove_file( | ||||
| &mut self, | &mut self, | ||||
| filename: &HgPath, | filename: &HgPath, | ||||
| in_merge: bool, | in_merge: bool, | ||||
| ) -> Result<(), DirstateError>; | ) -> Result<(), DirstateError>; | ||||
| self.set_entry(&filename, entry); | self.set_entry(&filename, entry); | ||||
| Ok(()) | Ok(()) | ||||
| } | } | ||||
| fn add_file( | fn add_file( | ||||
| &mut self, | &mut self, | ||||
| filename: &HgPath, | filename: &HgPath, | ||||
| entry: DirstateEntry, | entry: DirstateEntry, | ||||
| added: bool, | |||||
| merged: bool, | |||||
| from_p2: bool, | |||||
| possibly_dirty: bool, | |||||
| ) -> Result<(), DirstateError> { | ) -> Result<(), DirstateError> { | ||||
| self.add_file(filename, entry, added, merged, from_p2, possibly_dirty) | self.add_file(filename, entry) | ||||
| } | } | ||||
| fn remove_file( | fn remove_file( | ||||
| &mut self, | &mut self, | ||||
| filename: &HgPath, | filename: &HgPath, | ||||
| in_merge: bool, | in_merge: bool, | ||||
| ) -> Result<(), DirstateError> { | ) -> Result<(), DirstateError> { | ||||
| self.remove_file(filename, in_merge) | self.remove_file(filename, in_merge) | ||||
| ) -> Result<(), DirstateV2ParseError> { | ) -> Result<(), DirstateV2ParseError> { | ||||
| self.get_mut().set_entry(filename, entry) | self.get_mut().set_entry(filename, entry) | ||||
| } | } | ||||
| fn add_file( | fn add_file( | ||||
| &mut self, | &mut self, | ||||
| filename: &HgPath, | filename: &HgPath, | ||||
| entry: DirstateEntry, | entry: DirstateEntry, | ||||
| added: bool, | |||||
| merged: bool, | |||||
| from_p2: bool, | |||||
| possibly_dirty: bool, | |||||
| ) -> Result<(), DirstateError> { | ) -> Result<(), DirstateError> { | ||||
| self.get_mut().add_file( | self.get_mut().add_file(filename, entry) | ||||
| filename, | |||||
| entry, | |||||
| added, | |||||
| merged, | |||||
| from_p2, | |||||
| possibly_dirty, | |||||
| ) | |||||
| } | } | ||||
| fn remove_file( | fn remove_file( | ||||
| &mut self, | &mut self, | ||||
| filename: &HgPath, | filename: &HgPath, | ||||
| in_merge: bool, | in_merge: bool, | ||||
| ) -> Result<(), DirstateError> { | ) -> Result<(), DirstateError> { | ||||
| self.get_mut().remove_file(filename, in_merge) | self.get_mut().remove_file(filename, in_merge) | ||||
| dirstate::item::DirstateItem, | dirstate::item::DirstateItem, | ||||
| dirstate::non_normal_entries::{ | dirstate::non_normal_entries::{ | ||||
| NonNormalEntries, NonNormalEntriesIterator, | NonNormalEntries, NonNormalEntriesIterator, | ||||
| }, | }, | ||||
| pybytes_deref::PyBytesDeref, | pybytes_deref::PyBytesDeref, | ||||
| }; | }; | ||||
| use hg::{ | use hg::{ | ||||
| dirstate::parsers::Timestamp, | dirstate::parsers::Timestamp, | ||||
| dirstate::MTIME_UNSET, | |||||
| dirstate::SIZE_NON_NORMAL, | |||||
| dirstate_tree::dirstate_map::DirstateMap as TreeDirstateMap, | dirstate_tree::dirstate_map::DirstateMap as TreeDirstateMap, | ||||
| dirstate_tree::dispatch::DirstateMapMethods, | dirstate_tree::dispatch::DirstateMapMethods, | ||||
| dirstate_tree::on_disk::DirstateV2ParseError, | dirstate_tree::on_disk::DirstateV2ParseError, | ||||
| dirstate_tree::owning::OwningDirstateMap, | dirstate_tree::owning::OwningDirstateMap, | ||||
| revlog::Node, | revlog::Node, | ||||
| utils::files::normalize_case, | utils::files::normalize_case, | ||||
| utils::hg_path::{HgPath, HgPathBuf}, | utils::hg_path::{HgPath, HgPathBuf}, | ||||
| DirstateEntry, DirstateError, DirstateMap as RustDirstateMap, | DirstateEntry, DirstateError, DirstateMap as RustDirstateMap, | ||||
| .borrow_mut() | .borrow_mut() | ||||
| .set_entry(filename, item.get_entry(py)) | .set_entry(filename, item.get_entry(py)) | ||||
| .map_err(|e| v2_error(py, e))?; | .map_err(|e| v2_error(py, e))?; | ||||
| Ok(py.None()) | Ok(py.None()) | ||||
| } | } | ||||
| def addfile( | def addfile( | ||||
| &self, | &self, | ||||
| f: PyObject, | f: PyBytes, | ||||
| mode: PyObject, | item: DirstateItem, | ||||
| size: PyObject, | ) -> PyResult<PyNone> { | ||||
| mtime: PyObject, | |||||
| added: PyObject, | |||||
| merged: PyObject, | |||||
| from_p2: PyObject, | |||||
| possibly_dirty: PyObject, | |||||
| ) -> PyResult<PyObject> { | |||||
| let f = f.extract::<PyBytes>(py)?; | |||||
| let filename = HgPath::new(f.data(py)); | let filename = HgPath::new(f.data(py)); | ||||
| let mode = if mode.is_none(py) { | let entry = item.get_entry(py); | ||||
| // fallback default value | self.inner(py) | ||||
| 0 | .borrow_mut() | ||||
| } else { | .add_file(filename, entry) | ||||
| mode.extract(py)? | .map_err(|e |dirstate_error(py, e))?; | ||||
| }; | Ok(PyNone) | ||||
| let size = if size.is_none(py) { | |||||
| // fallback default value | |||||
| SIZE_NON_NORMAL | |||||
| } else { | |||||
| size.extract(py)? | |||||
| }; | |||||
| let mtime = if mtime.is_none(py) { | |||||
| // fallback default value | |||||
| MTIME_UNSET | |||||
| } else { | |||||
| mtime.extract(py)? | |||||
| }; | |||||
| let entry = DirstateEntry::new_for_add_file(mode, size, mtime); | |||||
| let added = added.extract::<PyBool>(py)?.is_true(); | |||||
| let merged = merged.extract::<PyBool>(py)?.is_true(); | |||||
| let from_p2 = from_p2.extract::<PyBool>(py)?.is_true(); | |||||
| let possibly_dirty = possibly_dirty.extract::<PyBool>(py)?.is_true(); | |||||
| self.inner(py).borrow_mut().add_file( | |||||
| filename, | |||||
| entry, | |||||
| added, | |||||
| merged, | |||||
| from_p2, | |||||
| possibly_dirty | |||||
| ).and(Ok(py.None())).or_else(|e: DirstateError| { | |||||
| Err(PyErr::new::<exc::ValueError, _>(py, e.to_string())) | |||||
| }) | |||||
| } | } | ||||
| 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() | ||||
| let state = <[u8; 1]>::try_from(state.data(py)) | let state = <[u8; 1]>::try_from(state.data(py)) | ||||
| .ok() | .ok() | ||||
| .and_then(|state| EntryState::try_from(state[0]).ok()) | .and_then(|state| EntryState::try_from(state[0]).ok()) | ||||
| .ok_or_else(|| PyErr::new::<exc::ValueError, _>(py, "invalid state"))?; | .ok_or_else(|| PyErr::new::<exc::ValueError, _>(py, "invalid state"))?; | ||||
| let entry = DirstateEntry::from_v1_data(state, mode, size, mtime); | let entry = DirstateEntry::from_v1_data(state, mode, size, mtime); | ||||
| DirstateItem::create_instance(py, Cell::new(entry)) | DirstateItem::create_instance(py, Cell::new(entry)) | ||||
| } | } | ||||
| @classmethod | |||||
| def new_added(_cls) -> PyResult<Self> { | |||||
| let entry = DirstateEntry::new_added(); | |||||
| DirstateItem::create_instance(py, Cell::new(entry)) | |||||
| } | |||||
| @classmethod | |||||
| def new_merged(_cls) -> PyResult<Self> { | |||||
| let entry = DirstateEntry::new_merged(); | |||||
| DirstateItem::create_instance(py, Cell::new(entry)) | |||||
| } | |||||
| @classmethod | |||||
| def new_from_p2(_cls) -> PyResult<Self> { | |||||
| let entry = DirstateEntry::new_from_p2(); | |||||
| DirstateItem::create_instance(py, Cell::new(entry)) | |||||
| } | |||||
| @classmethod | |||||
| def new_possibly_dirty(_cls) -> PyResult<Self> { | |||||
| let entry = DirstateEntry::new_possibly_dirty(); | |||||
| DirstateItem::create_instance(py, Cell::new(entry)) | |||||
| } | |||||
| @classmethod | |||||
| def new_normal(_cls, mode: i32, size: i32, mtime: i32) -> PyResult<Self> { | |||||
| let entry = DirstateEntry::new_normal(mode, size, mtime); | |||||
| DirstateItem::create_instance(py, Cell::new(entry)) | |||||
| } | |||||
| def set_clean( | def set_clean( | ||||
| &self, | &self, | ||||
| mode: i32, | mode: i32, | ||||
| size: i32, | size: i32, | ||||
| mtime: i32, | mtime: i32, | ||||
| ) -> PyResult<PyNone> { | ) -> PyResult<PyNone> { | ||||
| self.update(py, |entry| entry.set_clean(mode, size, mtime)); | self.update(py, |entry| entry.set_clean(mode, size, mtime)); | ||||
| Ok(PyNone) | Ok(PyNone) | ||||