##// END OF EJS Templates
dirstate: move most of the `remove` logic with dirstatemap `removefile`...
marmoute -
r48300:eaae3989 default
parent child Browse files
Show More
@@ -559,21 +559,8 b' class dirstate(object):'
559 def remove(self, f):
559 def remove(self, f):
560 '''Mark a file removed.'''
560 '''Mark a file removed.'''
561 self._dirty = True
561 self._dirty = True
562 oldstate = self[f]
563 size = 0
564 if self.in_merge:
565 entry = self._map.get(f)
566 if entry is not None:
567 # backup the previous state
568 if entry[0] == b'm': # merge
569 size = NONNORMAL
570 elif entry[0] == b'n' and entry[2] == FROM_P2: # other parent
571 size = FROM_P2
572 self._map.otherparentset.add(f)
573 self._updatedfiles.add(f)
562 self._updatedfiles.add(f)
574 self._map.removefile(f, oldstate, size)
563 self._map.removefile(f, in_merge=self.in_merge)
575 if size == 0:
576 self._map.copymap.pop(f, None)
577
564
578 def merge(self, f):
565 def merge(self, f):
579 '''Mark a file merged.'''
566 '''Mark a file merged.'''
@@ -154,7 +154,7 b' class dirstatemap(object):'
154 if size == FROM_P2:
154 if size == FROM_P2:
155 self.otherparentset.add(f)
155 self.otherparentset.add(f)
156
156
157 def removefile(self, f, oldstate, size):
157 def removefile(self, f, in_merge=False):
158 """
158 """
159 Mark a file as removed in the dirstate.
159 Mark a file as removed in the dirstate.
160
160
@@ -162,9 +162,26 b' class dirstatemap(object):'
162 the file's previous state. In the future, we should refactor this
162 the file's previous state. In the future, we should refactor this
163 to be more explicit about what that state is.
163 to be more explicit about what that state is.
164 """
164 """
165 if oldstate not in b"?r" and "_dirs" in self.__dict__:
165 entry = self.get(f)
166 size = 0
167 if in_merge:
168 # XXX we should not be able to have 'm' state and 'FROM_P2' if not
169 # during a merge. So I (marmoute) am not sure we need the
170 # conditionnal at all. Adding double checking this with assert
171 # would be nice.
172 if entry is not None:
173 # backup the previous state
174 if entry[0] == b'm': # merge
175 size = NONNORMAL
176 elif entry[0] == b'n' and entry[2] == FROM_P2: # other parent
177 size = FROM_P2
178 self.otherparentset.add(f)
179 if size == 0:
180 self.copymap.pop(f, None)
181
182 if entry is not None and entry[0] != b'r' and "_dirs" in self.__dict__:
166 self._dirs.delpath(f)
183 self._dirs.delpath(f)
167 if oldstate == b"?" and "_alldirs" in self.__dict__:
184 if entry is None and "_alldirs" in self.__dict__:
168 self._alldirs.addpath(f)
185 self._alldirs.addpath(f)
169 if "filefoldmap" in self.__dict__:
186 if "filefoldmap" in self.__dict__:
170 normed = util.normcase(f)
187 normed = util.normcase(f)
@@ -83,6 +83,9 b' const MTIME_UNSET: i32 = -1;'
83 /// other parent. This allows revert to pick the right status back during a
83 /// other parent. This allows revert to pick the right status back during a
84 /// merge.
84 /// merge.
85 pub const SIZE_FROM_OTHER_PARENT: i32 = -2;
85 pub const SIZE_FROM_OTHER_PARENT: i32 = -2;
86 /// A special value used for internal representation of special case in
87 /// dirstate v1 format.
88 pub const SIZE_NON_NORMAL: i32 = -1;
86
89
87 pub type StateMap = FastHashMap<HgPathBuf, DirstateEntry>;
90 pub type StateMap = FastHashMap<HgPathBuf, DirstateEntry>;
88 pub type StateMapIter<'a> = Box<
91 pub type StateMapIter<'a> = Box<
@@ -8,6 +8,8 b''
8 use crate::dirstate::parsers::Timestamp;
8 use crate::dirstate::parsers::Timestamp;
9 use crate::{
9 use crate::{
10 dirstate::EntryState,
10 dirstate::EntryState,
11 dirstate::SIZE_FROM_OTHER_PARENT,
12 dirstate::SIZE_NON_NORMAL,
11 pack_dirstate, parse_dirstate,
13 pack_dirstate, parse_dirstate,
12 utils::hg_path::{HgPath, HgPathBuf},
14 utils::hg_path::{HgPath, HgPathBuf},
13 CopyMap, DirsMultiset, DirstateEntry, DirstateError, DirstateParents,
15 CopyMap, DirsMultiset, DirstateEntry, DirstateError, DirstateParents,
@@ -102,9 +104,34 b' impl DirstateMap {'
102 pub fn remove_file(
104 pub fn remove_file(
103 &mut self,
105 &mut self,
104 filename: &HgPath,
106 filename: &HgPath,
105 old_state: EntryState,
107 in_merge: bool,
106 size: i32,
107 ) -> Result<(), DirstateError> {
108 ) -> Result<(), DirstateError> {
109 let old_entry_opt = self.get(filename);
110 let old_state = match old_entry_opt {
111 Some(e) => e.state,
112 None => EntryState::Unknown,
113 };
114 let mut size = 0;
115 if in_merge {
116 // XXX we should not be able to have 'm' state and 'FROM_P2' if not
117 // during a merge. So I (marmoute) am not sure we need the
118 // conditionnal at all. Adding double checking this with assert
119 // would be nice.
120 if let Some(old_entry) = old_entry_opt {
121 // backup the previous state
122 if old_entry.state == EntryState::Merged {
123 size = SIZE_NON_NORMAL;
124 } else if old_entry.state == EntryState::Normal
125 && old_entry.size == SIZE_FROM_OTHER_PARENT
126 {
127 // other parent
128 size = SIZE_FROM_OTHER_PARENT;
129 self.get_non_normal_other_parent_entries()
130 .1
131 .insert(filename.to_owned());
132 }
133 }
134 }
108 if old_state != EntryState::Unknown && old_state != EntryState::Removed
135 if old_state != EntryState::Unknown && old_state != EntryState::Removed
109 {
136 {
110 if let Some(ref mut dirs) = self.dirs {
137 if let Some(ref mut dirs) = self.dirs {
@@ -116,6 +143,9 b' impl DirstateMap {'
116 all_dirs.add_path(filename)?;
143 all_dirs.add_path(filename)?;
117 }
144 }
118 }
145 }
146 if size == 0 {
147 self.copy_map.remove(filename);
148 }
119
149
120 self.state_map.insert(
150 self.state_map.insert(
121 filename.to_owned(),
151 filename.to_owned(),
@@ -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::parsers::Timestamp;
13 use crate::dirstate::parsers::Timestamp;
14 use crate::dirstate::SIZE_FROM_OTHER_PARENT;
15 use crate::dirstate::SIZE_NON_NORMAL;
14 use crate::matchers::Matcher;
16 use crate::matchers::Matcher;
15 use crate::utils::hg_path::{HgPath, HgPathBuf};
17 use crate::utils::hg_path::{HgPath, HgPathBuf};
16 use crate::CopyMapIter;
18 use crate::CopyMapIter;
@@ -726,9 +728,34 b" impl<'on_disk> super::dispatch::Dirstate"
726 fn remove_file(
728 fn remove_file(
727 &mut self,
729 &mut self,
728 filename: &HgPath,
730 filename: &HgPath,
729 old_state: EntryState,
731 in_merge: bool,
730 size: i32,
731 ) -> Result<(), DirstateError> {
732 ) -> Result<(), DirstateError> {
733 let old_entry_opt = self.get(filename)?;
734 let old_state = match old_entry_opt {
735 Some(e) => e.state,
736 None => EntryState::Unknown,
737 };
738 let mut size = 0;
739 if in_merge {
740 // XXX we should not be able to have 'm' state and 'FROM_P2' if not
741 // during a merge. So I (marmoute) am not sure we need the
742 // conditionnal at all. Adding double checking this with assert
743 // would be nice.
744 if let Some(old_entry) = old_entry_opt {
745 // backup the previous state
746 if old_entry.state == EntryState::Merged {
747 size = SIZE_NON_NORMAL;
748 } else if old_entry.state == EntryState::Normal
749 && old_entry.size == SIZE_FROM_OTHER_PARENT
750 {
751 // other parent
752 size = SIZE_FROM_OTHER_PARENT;
753 }
754 }
755 }
756 if size == 0 {
757 self.copy_map_remove(filename)?;
758 }
732 let entry = DirstateEntry {
759 let entry = DirstateEntry {
733 state: EntryState::Removed,
760 state: EntryState::Removed,
734 mode: 0,
761 mode: 0,
@@ -61,8 +61,7 b' pub trait DirstateMapMethods {'
61 fn remove_file(
61 fn remove_file(
62 &mut self,
62 &mut self,
63 filename: &HgPath,
63 filename: &HgPath,
64 old_state: EntryState,
64 in_merge: bool,
65 size: i32,
66 ) -> Result<(), DirstateError>;
65 ) -> Result<(), DirstateError>;
67
66
68 /// Drop information about this file from the map if any, and return
67 /// Drop information about this file from the map if any, and return
@@ -295,10 +294,9 b' impl DirstateMapMethods for DirstateMap '
295 fn remove_file(
294 fn remove_file(
296 &mut self,
295 &mut self,
297 filename: &HgPath,
296 filename: &HgPath,
298 old_state: EntryState,
297 in_merge: bool,
299 size: i32,
300 ) -> Result<(), DirstateError> {
298 ) -> Result<(), DirstateError> {
301 self.remove_file(filename, old_state, size)
299 self.remove_file(filename, in_merge)
302 }
300 }
303
301
304 fn drop_file(
302 fn drop_file(
@@ -137,18 +137,12 b' py_class!(pub class DirstateMap |py| {'
137 def removefile(
137 def removefile(
138 &self,
138 &self,
139 f: PyObject,
139 f: PyObject,
140 oldstate: PyObject,
140 in_merge: PyObject
141 size: PyObject
142 ) -> PyResult<PyObject> {
141 ) -> PyResult<PyObject> {
143 self.inner(py).borrow_mut()
142 self.inner(py).borrow_mut()
144 .remove_file(
143 .remove_file(
145 HgPath::new(f.extract::<PyBytes>(py)?.data(py)),
144 HgPath::new(f.extract::<PyBytes>(py)?.data(py)),
146 oldstate.extract::<PyBytes>(py)?.data(py)[0]
145 in_merge.extract::<PyBool>(py)?.is_true(),
147 .try_into()
148 .map_err(|e: HgError| {
149 PyErr::new::<exc::ValueError, _>(py, e.to_string())
150 })?,
151 size.extract(py)?,
152 )
146 )
153 .or_else(|_| {
147 .or_else(|_| {
154 Err(PyErr::new::<exc::OSError, _>(
148 Err(PyErr::new::<exc::OSError, _>(
@@ -33,10 +33,9 b' impl DirstateMapMethods for OwningDirsta'
33 fn remove_file(
33 fn remove_file(
34 &mut self,
34 &mut self,
35 filename: &HgPath,
35 filename: &HgPath,
36 old_state: EntryState,
36 in_merge: bool,
37 size: i32,
38 ) -> Result<(), DirstateError> {
37 ) -> Result<(), DirstateError> {
39 self.get_mut().remove_file(filename, old_state, size)
38 self.get_mut().remove_file(filename, in_merge)
40 }
39 }
41
40
42 fn drop_file(
41 fn drop_file(
General Comments 0
You need to be logged in to leave comments. Login now