Show More
@@ -564,30 +564,46 b' class dirstate(object):' | |||||
564 | if merged and (clean_p1 or clean_p2): |
|
564 | if merged and (clean_p1 or clean_p2): | |
565 | msg = b'`merged` argument incompatible with `clean_p1`/`clean_p2`' |
|
565 | msg = b'`merged` argument incompatible with `clean_p1`/`clean_p2`' | |
566 | raise error.ProgrammingError(msg) |
|
566 | raise error.ProgrammingError(msg) | |
567 | if not (p1_tracked or p2_tracked or wc_tracked): |
|
567 | ||
568 | self._drop(filename) |
|
568 | # note: I do not think we need to double check name clash here since we | |
569 | elif merged: |
|
569 | # are in a update/merge case that should already have taken care of | |
570 | assert wc_tracked |
|
570 | # this. The test agrees | |
571 | assert self.in_merge # we are never in the "normallookup" case |
|
571 | ||
572 | self.otherparent(filename) |
|
572 | self._dirty = True | |
573 | elif not (p1_tracked or p2_tracked) and wc_tracked: |
|
573 | self._updatedfiles.add(filename) | |
574 | self._addpath(filename, added=True, possibly_dirty=possibly_dirty) |
|
574 | ||
575 | self._map.copymap.pop(filename, None) |
|
575 | need_parent_file_data = ( | |
576 | elif (p1_tracked or p2_tracked) and not wc_tracked: |
|
576 | not (possibly_dirty or clean_p2 or merged) | |
577 | self._remove(filename) |
|
577 | and wc_tracked | |
578 |
|
|
578 | and p1_tracked | |
579 | assert p2_tracked |
|
579 | ) | |
580 | self.otherparent(filename) |
|
580 | ||
581 | elif not p1_tracked and p2_tracked and wc_tracked: |
|
581 | # this mean we are doing call for file we do not really care about the | |
582 | self._addpath(filename, from_p2=True, possibly_dirty=possibly_dirty) |
|
582 | # data (eg: added or removed), however this should be a minor overhead | |
583 | self._map.copymap.pop(filename, None) |
|
583 | # compared to the overall update process calling this. | |
584 | elif possibly_dirty: |
|
584 | if need_parent_file_data: | |
585 | self._addpath(filename, possibly_dirty=possibly_dirty) |
|
585 | if parentfiledata is None: | |
586 | elif wc_tracked: |
|
586 | parentfiledata = self._get_filedata(filename) | |
587 |
|
|
587 | mtime = parentfiledata[2] | |
588 | # XXX We need something for file that are dirty after an update |
|
588 | ||
589 | else: |
|
589 | if mtime > self._lastnormaltime: | |
590 | assert False, 'unreachable' |
|
590 | # Remember the most recent modification timeslot for | |
|
591 | # status(), to make sure we won't miss future | |||
|
592 | # size-preserving file content modifications that happen | |||
|
593 | # within the same timeslot. | |||
|
594 | self._lastnormaltime = mtime | |||
|
595 | ||||
|
596 | self._map.reset_state( | |||
|
597 | filename, | |||
|
598 | wc_tracked, | |||
|
599 | p1_tracked, | |||
|
600 | p2_tracked=p2_tracked, | |||
|
601 | merged=merged, | |||
|
602 | clean_p1=clean_p1, | |||
|
603 | clean_p2=clean_p2, | |||
|
604 | possibly_dirty=possibly_dirty, | |||
|
605 | parentfiledata=parentfiledata, | |||
|
606 | ) | |||
591 |
|
607 | |||
592 | def _addpath( |
|
608 | def _addpath( | |
593 | self, |
|
609 | self, |
@@ -219,6 +219,83 b' class dirstatemap(object):' | |||||
219 | if e.dm_otherparent: |
|
219 | if e.dm_otherparent: | |
220 | self.otherparentset.add(f) |
|
220 | self.otherparentset.add(f) | |
221 |
|
221 | |||
|
222 | def reset_state( | |||
|
223 | self, | |||
|
224 | filename, | |||
|
225 | wc_tracked, | |||
|
226 | p1_tracked, | |||
|
227 | p2_tracked=False, | |||
|
228 | merged=False, | |||
|
229 | clean_p1=False, | |||
|
230 | clean_p2=False, | |||
|
231 | possibly_dirty=False, | |||
|
232 | parentfiledata=None, | |||
|
233 | ): | |||
|
234 | """Set a entry to a given state, diregarding all previous state | |||
|
235 | ||||
|
236 | This is to be used by the part of the dirstate API dedicated to | |||
|
237 | adjusting the dirstate after a update/merge. | |||
|
238 | ||||
|
239 | note: calling this might result to no entry existing at all if the | |||
|
240 | dirstate map does not see any point at having one for this file | |||
|
241 | anymore. | |||
|
242 | """ | |||
|
243 | if merged and (clean_p1 or clean_p2): | |||
|
244 | msg = b'`merged` argument incompatible with `clean_p1`/`clean_p2`' | |||
|
245 | raise error.ProgrammingError(msg) | |||
|
246 | # copy information are now outdated | |||
|
247 | # (maybe new information should be in directly passed to this function) | |||
|
248 | self.copymap.pop(filename, None) | |||
|
249 | ||||
|
250 | if not (p1_tracked or p2_tracked or wc_tracked): | |||
|
251 | self.dropfile(filename) | |||
|
252 | elif merged: | |||
|
253 | # XXX might be merged and removed ? | |||
|
254 | entry = self.get(filename) | |||
|
255 | if entry is not None and entry.tracked: | |||
|
256 | # XXX mostly replicate dirstate.other parent. We should get | |||
|
257 | # the higher layer to pass us more reliable data where `merged` | |||
|
258 | # actually mean merged. Dropping the else clause will show | |||
|
259 | # failure in `test-graft.t` | |||
|
260 | self.addfile(filename, merged=True) | |||
|
261 | else: | |||
|
262 | self.addfile(filename, from_p2=True) | |||
|
263 | elif not (p1_tracked or p2_tracked) and wc_tracked: | |||
|
264 | self.addfile(filename, added=True, possibly_dirty=possibly_dirty) | |||
|
265 | elif (p1_tracked or p2_tracked) and not wc_tracked: | |||
|
266 | # XXX might be merged and removed ? | |||
|
267 | old_entry = self._map.get(filename) | |||
|
268 | self._dirs_decr(filename, old_entry=old_entry, remove_variant=True) | |||
|
269 | self._map[filename] = DirstateItem(b'r', 0, 0, 0) | |||
|
270 | self.nonnormalset.add(filename) | |||
|
271 | elif clean_p2 and wc_tracked: | |||
|
272 | if p1_tracked or self.get(filename) is not None: | |||
|
273 | # XXX the `self.get` call is catching some case in | |||
|
274 | # `test-merge-remove.t` where the file is tracked in p1, the | |||
|
275 | # p1_tracked argument is False. | |||
|
276 | # | |||
|
277 | # In addition, this seems to be a case where the file is marked | |||
|
278 | # as merged without actually being the result of a merge | |||
|
279 | # action. So thing are not ideal here. | |||
|
280 | self.addfile(filename, merged=True) | |||
|
281 | else: | |||
|
282 | self.addfile(filename, from_p2=True) | |||
|
283 | elif not p1_tracked and p2_tracked and wc_tracked: | |||
|
284 | self.addfile(filename, from_p2=True, possibly_dirty=possibly_dirty) | |||
|
285 | elif possibly_dirty: | |||
|
286 | self.addfile(filename, possibly_dirty=possibly_dirty) | |||
|
287 | elif wc_tracked: | |||
|
288 | # this is a "normal" file | |||
|
289 | if parentfiledata is None: | |||
|
290 | msg = b'failed to pass parentfiledata for a normal file: %s' | |||
|
291 | msg %= filename | |||
|
292 | raise error.ProgrammingError(msg) | |||
|
293 | mode, size, mtime = parentfiledata | |||
|
294 | self.addfile(filename, mode=mode, size=size, mtime=mtime) | |||
|
295 | self.nonnormalset.discard(filename) | |||
|
296 | else: | |||
|
297 | assert False, 'unreachable' | |||
|
298 | ||||
222 | def removefile(self, f, in_merge=False): |
|
299 | def removefile(self, f, in_merge=False): | |
223 | """ |
|
300 | """ | |
224 | Mark a file as removed in the dirstate. |
|
301 | Mark a file as removed in the dirstate. | |
@@ -499,6 +576,87 b' if rustmod is not None:' | |||||
499 | possibly_dirty, |
|
576 | possibly_dirty, | |
500 | ) |
|
577 | ) | |
501 |
|
578 | |||
|
579 | def reset_state( | |||
|
580 | self, | |||
|
581 | filename, | |||
|
582 | wc_tracked, | |||
|
583 | p1_tracked, | |||
|
584 | p2_tracked=False, | |||
|
585 | merged=False, | |||
|
586 | clean_p1=False, | |||
|
587 | clean_p2=False, | |||
|
588 | possibly_dirty=False, | |||
|
589 | parentfiledata=None, | |||
|
590 | ): | |||
|
591 | """Set a entry to a given state, disregarding all previous state | |||
|
592 | ||||
|
593 | This is to be used by the part of the dirstate API dedicated to | |||
|
594 | adjusting the dirstate after a update/merge. | |||
|
595 | ||||
|
596 | note: calling this might result to no entry existing at all if the | |||
|
597 | dirstate map does not see any point at having one for this file | |||
|
598 | anymore. | |||
|
599 | """ | |||
|
600 | if merged and (clean_p1 or clean_p2): | |||
|
601 | msg = ( | |||
|
602 | b'`merged` argument incompatible with `clean_p1`/`clean_p2`' | |||
|
603 | ) | |||
|
604 | raise error.ProgrammingError(msg) | |||
|
605 | # copy information are now outdated | |||
|
606 | # (maybe new information should be in directly passed to this function) | |||
|
607 | self.copymap.pop(filename, None) | |||
|
608 | ||||
|
609 | if not (p1_tracked or p2_tracked or wc_tracked): | |||
|
610 | self.dropfile(filename) | |||
|
611 | elif merged: | |||
|
612 | # XXX might be merged and removed ? | |||
|
613 | entry = self.get(filename) | |||
|
614 | if entry is not None and entry.tracked: | |||
|
615 | # XXX mostly replicate dirstate.other parent. We should get | |||
|
616 | # the higher layer to pass us more reliable data where `merged` | |||
|
617 | # actually mean merged. Dropping the else clause will show | |||
|
618 | # failure in `test-graft.t` | |||
|
619 | self.addfile(filename, merged=True) | |||
|
620 | else: | |||
|
621 | self.addfile(filename, from_p2=True) | |||
|
622 | elif not (p1_tracked or p2_tracked) and wc_tracked: | |||
|
623 | self.addfile( | |||
|
624 | filename, added=True, possibly_dirty=possibly_dirty | |||
|
625 | ) | |||
|
626 | elif (p1_tracked or p2_tracked) and not wc_tracked: | |||
|
627 | # XXX might be merged and removed ? | |||
|
628 | self[filename] = DirstateItem(b'r', 0, 0, 0) | |||
|
629 | self.nonnormalset.add(filename) | |||
|
630 | elif clean_p2 and wc_tracked: | |||
|
631 | if p1_tracked or self.get(filename) is not None: | |||
|
632 | # XXX the `self.get` call is catching some case in | |||
|
633 | # `test-merge-remove.t` where the file is tracked in p1, the | |||
|
634 | # p1_tracked argument is False. | |||
|
635 | # | |||
|
636 | # In addition, this seems to be a case where the file is marked | |||
|
637 | # as merged without actually being the result of a merge | |||
|
638 | # action. So thing are not ideal here. | |||
|
639 | self.addfile(filename, merged=True) | |||
|
640 | else: | |||
|
641 | self.addfile(filename, from_p2=True) | |||
|
642 | elif not p1_tracked and p2_tracked and wc_tracked: | |||
|
643 | self.addfile( | |||
|
644 | filename, from_p2=True, possibly_dirty=possibly_dirty | |||
|
645 | ) | |||
|
646 | elif possibly_dirty: | |||
|
647 | self.addfile(filename, possibly_dirty=possibly_dirty) | |||
|
648 | elif wc_tracked: | |||
|
649 | # this is a "normal" file | |||
|
650 | if parentfiledata is None: | |||
|
651 | msg = b'failed to pass parentfiledata for a normal file: %s' | |||
|
652 | msg %= filename | |||
|
653 | raise error.ProgrammingError(msg) | |||
|
654 | mode, size, mtime = parentfiledata | |||
|
655 | self.addfile(filename, mode=mode, size=size, mtime=mtime) | |||
|
656 | self.nonnormalset.discard(filename) | |||
|
657 | else: | |||
|
658 | assert False, 'unreachable' | |||
|
659 | ||||
502 | def removefile(self, *args, **kwargs): |
|
660 | def removefile(self, *args, **kwargs): | |
503 | return self._rustmap.removefile(*args, **kwargs) |
|
661 | return self._rustmap.removefile(*args, **kwargs) | |
504 |
|
662 | |||
@@ -748,3 +906,7 b' if rustmod is not None:' | |||||
748 | for name in self._rustmap.tracked_dirs(): |
|
906 | for name in self._rustmap.tracked_dirs(): | |
749 | f[normcase(name)] = name |
|
907 | f[normcase(name)] = name | |
750 | return f |
|
908 | return f | |
|
909 | ||||
|
910 | def __setitem__(self, key, value): | |||
|
911 | assert isinstance(value, DirstateItem) | |||
|
912 | self._rustmap.set_v1(key, value) |
@@ -64,6 +64,10 b' impl DirstateMap {' | |||||
64 | self.other_parent_set = None; |
|
64 | self.other_parent_set = None; | |
65 | } |
|
65 | } | |
66 |
|
66 | |||
|
67 | pub fn set_v1_inner(&mut self, filename: &HgPath, entry: DirstateEntry) { | |||
|
68 | self.state_map.insert(filename.to_owned(), entry); | |||
|
69 | } | |||
|
70 | ||||
67 | /// Add a tracked file to the dirstate |
|
71 | /// Add a tracked file to the dirstate | |
68 | pub fn add_file( |
|
72 | pub fn add_file( | |
69 | &mut self, |
|
73 | &mut self, | |
@@ -245,10 +249,19 b' impl DirstateMap {' | |||||
245 | } |
|
249 | } | |
246 | } |
|
250 | } | |
247 |
|
251 | |||
248 |
pub fn non_normal_entries_remove( |
|
252 | pub fn non_normal_entries_remove( | |
|
253 | &mut self, | |||
|
254 | key: impl AsRef<HgPath>, | |||
|
255 | ) -> bool { | |||
249 | self.get_non_normal_other_parent_entries() |
|
256 | self.get_non_normal_other_parent_entries() | |
250 | .0 |
|
257 | .0 | |
251 |
.remove(key.as_ref()) |
|
258 | .remove(key.as_ref()) | |
|
259 | } | |||
|
260 | ||||
|
261 | pub fn non_normal_entries_add(&mut self, key: impl AsRef<HgPath>) { | |||
|
262 | self.get_non_normal_other_parent_entries() | |||
|
263 | .0 | |||
|
264 | .insert(key.as_ref().into()); | |||
252 | } |
|
265 | } | |
253 |
|
266 | |||
254 | pub fn non_normal_entries_union( |
|
267 | pub fn non_normal_entries_union( |
@@ -757,6 +757,16 b" impl<'on_disk> super::dispatch::Dirstate" | |||||
757 | self.nodes_with_copy_source_count = 0; |
|
757 | self.nodes_with_copy_source_count = 0; | |
758 | } |
|
758 | } | |
759 |
|
759 | |||
|
760 | fn set_v1(&mut self, filename: &HgPath, entry: DirstateEntry) { | |||
|
761 | let node = | |||
|
762 | self.get_or_insert(&filename).expect("no parse error in v1"); | |||
|
763 | node.data = NodeData::Entry(entry); | |||
|
764 | node.children = ChildNodes::default(); | |||
|
765 | node.copy_source = None; | |||
|
766 | node.descendants_with_entry_count = 0; | |||
|
767 | node.tracked_descendants_count = 0; | |||
|
768 | } | |||
|
769 | ||||
760 | fn add_file( |
|
770 | fn add_file( | |
761 | &mut self, |
|
771 | &mut self, | |
762 | filename: &HgPath, |
|
772 | filename: &HgPath, | |
@@ -982,7 +992,16 b" impl<'on_disk> super::dispatch::Dirstate" | |||||
982 | }) |
|
992 | }) | |
983 | } |
|
993 | } | |
984 |
|
994 | |||
985 |
fn non_normal_entries_remove(&mut self, |
|
995 | fn non_normal_entries_remove(&mut self, key: &HgPath) -> bool { | |
|
996 | // Do nothing, this `DirstateMap` does not have a separate "non normal | |||
|
997 | // entries" set that need to be kept up to date. | |||
|
998 | if let Ok(Some(v)) = self.get(key) { | |||
|
999 | return v.is_non_normal(); | |||
|
1000 | } | |||
|
1001 | false | |||
|
1002 | } | |||
|
1003 | ||||
|
1004 | fn non_normal_entries_add(&mut self, _key: &HgPath) { | |||
986 | // Do nothing, this `DirstateMap` does not have a separate "non normal |
|
1005 | // Do nothing, this `DirstateMap` does not have a separate "non normal | |
987 | // entries" set that need to be kept up to date |
|
1006 | // entries" set that need to be kept up to date | |
988 | } |
|
1007 | } |
@@ -37,6 +37,8 b' pub trait DirstateMapMethods {' | |||||
37 | /// Remove information about all files in this map |
|
37 | /// Remove information about all files in this map | |
38 | fn clear(&mut self); |
|
38 | fn clear(&mut self); | |
39 |
|
39 | |||
|
40 | fn set_v1(&mut self, filename: &HgPath, entry: DirstateEntry); | |||
|
41 | ||||
40 | /// Add or change the information associated to a given file. |
|
42 | /// Add or change the information associated to a given file. | |
41 | /// |
|
43 | /// | |
42 | /// `old_state` is the state in the entry that `get` would have returned |
|
44 | /// `old_state` is the state in the entry that `get` would have returned | |
@@ -95,7 +97,13 b' pub trait DirstateMapMethods {' | |||||
95 | /// Mark the given path as "normal" file. This is only relevant in the flat |
|
97 | /// Mark the given path as "normal" file. This is only relevant in the flat | |
96 | /// dirstate map where there is a separate `HashSet` that needs to be kept |
|
98 | /// dirstate map where there is a separate `HashSet` that needs to be kept | |
97 | /// up to date. |
|
99 | /// up to date. | |
98 | fn non_normal_entries_remove(&mut self, key: &HgPath); |
|
100 | /// Returns whether the key was present in the set. | |
|
101 | fn non_normal_entries_remove(&mut self, key: &HgPath) -> bool; | |||
|
102 | ||||
|
103 | /// Mark the given path as "non-normal" file. | |||
|
104 | /// This is only relevant in the flat dirstate map where there is a | |||
|
105 | /// separate `HashSet` that needs to be kept up to date. | |||
|
106 | fn non_normal_entries_add(&mut self, key: &HgPath); | |||
99 |
|
107 | |||
100 | /// Return an iterator of paths whose respective entry are either |
|
108 | /// Return an iterator of paths whose respective entry are either | |
101 | /// "non-normal" (see `non_normal_entries_contains`) or "from other |
|
109 | /// "non-normal" (see `non_normal_entries_contains`) or "from other | |
@@ -305,6 +313,14 b' impl DirstateMapMethods for DirstateMap ' | |||||
305 | self.clear() |
|
313 | self.clear() | |
306 | } |
|
314 | } | |
307 |
|
315 | |||
|
316 | /// Used to set a value directory. | |||
|
317 | /// | |||
|
318 | /// XXX Is temporary during a refactor of V1 dirstate and will disappear | |||
|
319 | /// shortly. | |||
|
320 | fn set_v1(&mut self, filename: &HgPath, entry: DirstateEntry) { | |||
|
321 | self.set_v1_inner(&filename, entry) | |||
|
322 | } | |||
|
323 | ||||
308 | fn add_file( |
|
324 | fn add_file( | |
309 | &mut self, |
|
325 | &mut self, | |
310 | filename: &HgPath, |
|
326 | filename: &HgPath, | |
@@ -346,10 +362,14 b' impl DirstateMapMethods for DirstateMap ' | |||||
346 | Ok(non_normal.contains(key)) |
|
362 | Ok(non_normal.contains(key)) | |
347 | } |
|
363 | } | |
348 |
|
364 | |||
349 | fn non_normal_entries_remove(&mut self, key: &HgPath) { |
|
365 | fn non_normal_entries_remove(&mut self, key: &HgPath) -> bool { | |
350 | self.non_normal_entries_remove(key) |
|
366 | self.non_normal_entries_remove(key) | |
351 | } |
|
367 | } | |
352 |
|
368 | |||
|
369 | fn non_normal_entries_add(&mut self, key: &HgPath) { | |||
|
370 | self.non_normal_entries_add(key) | |||
|
371 | } | |||
|
372 | ||||
353 | fn non_normal_or_other_parent_paths( |
|
373 | fn non_normal_or_other_parent_paths( | |
354 | &mut self, |
|
374 | &mut self, | |
355 | ) -> Box<dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + '_> |
|
375 | ) -> Box<dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + '_> |
@@ -117,6 +117,21 b' py_class!(pub class DirstateMap |py| {' | |||||
117 | } |
|
117 | } | |
118 | } |
|
118 | } | |
119 |
|
119 | |||
|
120 | def set_v1(&self, path: PyObject, item: PyObject) -> PyResult<PyObject> { | |||
|
121 | let f = path.extract::<PyBytes>(py)?; | |||
|
122 | let filename = HgPath::new(f.data(py)); | |||
|
123 | let state = item.getattr(py, "state")?.extract::<PyBytes>(py)?; | |||
|
124 | let state = state.data(py)[0]; | |||
|
125 | let entry = DirstateEntry { | |||
|
126 | state: state.try_into().expect("state is always valid"), | |||
|
127 | mtime: item.getattr(py, "mtime")?.extract(py)?, | |||
|
128 | size: item.getattr(py, "size")?.extract(py)?, | |||
|
129 | mode: item.getattr(py, "mode")?.extract(py)?, | |||
|
130 | }; | |||
|
131 | self.inner(py).borrow_mut().set_v1(filename, entry); | |||
|
132 | Ok(py.None()) | |||
|
133 | } | |||
|
134 | ||||
120 | def addfile( |
|
135 | def addfile( | |
121 | &self, |
|
136 | &self, | |
122 | f: PyObject, |
|
137 | f: PyObject, | |
@@ -261,6 +276,22 b' py_class!(pub class DirstateMap |py| {' | |||||
261 |
|
276 | |||
262 | def non_normal_entries_remove(&self, key: PyObject) -> PyResult<PyObject> { |
|
277 | def non_normal_entries_remove(&self, key: PyObject) -> PyResult<PyObject> { | |
263 | let key = key.extract::<PyBytes>(py)?; |
|
278 | let key = key.extract::<PyBytes>(py)?; | |
|
279 | let key = key.data(py); | |||
|
280 | let was_present = self | |||
|
281 | .inner(py) | |||
|
282 | .borrow_mut() | |||
|
283 | .non_normal_entries_remove(HgPath::new(key)); | |||
|
284 | if !was_present { | |||
|
285 | let msg = String::from_utf8_lossy(key); | |||
|
286 | Err(PyErr::new::<exc::KeyError, _>(py, msg)) | |||
|
287 | } else { | |||
|
288 | Ok(py.None()) | |||
|
289 | } | |||
|
290 | } | |||
|
291 | ||||
|
292 | def non_normal_entries_discard(&self, key: PyObject) -> PyResult<PyObject> | |||
|
293 | { | |||
|
294 | let key = key.extract::<PyBytes>(py)?; | |||
264 | self |
|
295 | self | |
265 | .inner(py) |
|
296 | .inner(py) | |
266 | .borrow_mut() |
|
297 | .borrow_mut() | |
@@ -268,6 +299,15 b' py_class!(pub class DirstateMap |py| {' | |||||
268 | Ok(py.None()) |
|
299 | Ok(py.None()) | |
269 | } |
|
300 | } | |
270 |
|
301 | |||
|
302 | def non_normal_entries_add(&self, key: PyObject) -> PyResult<PyObject> { | |||
|
303 | let key = key.extract::<PyBytes>(py)?; | |||
|
304 | self | |||
|
305 | .inner(py) | |||
|
306 | .borrow_mut() | |||
|
307 | .non_normal_entries_add(HgPath::new(key.data(py))); | |||
|
308 | Ok(py.None()) | |||
|
309 | } | |||
|
310 | ||||
271 | def non_normal_or_other_parent_paths(&self) -> PyResult<PyList> { |
|
311 | def non_normal_or_other_parent_paths(&self) -> PyResult<PyList> { | |
272 | let mut inner = self.inner(py).borrow_mut(); |
|
312 | let mut inner = self.inner(py).borrow_mut(); | |
273 |
|
313 |
@@ -20,6 +20,10 b' impl DirstateMapMethods for OwningDirsta' | |||||
20 | self.get_mut().clear() |
|
20 | self.get_mut().clear() | |
21 | } |
|
21 | } | |
22 |
|
22 | |||
|
23 | fn set_v1(&mut self, filename: &HgPath, entry: DirstateEntry) { | |||
|
24 | self.get_mut().set_v1(filename, entry) | |||
|
25 | } | |||
|
26 | ||||
23 | fn add_file( |
|
27 | fn add_file( | |
24 | &mut self, |
|
28 | &mut self, | |
25 | filename: &HgPath, |
|
29 | filename: &HgPath, | |
@@ -66,10 +70,14 b' impl DirstateMapMethods for OwningDirsta' | |||||
66 | self.get_mut().non_normal_entries_contains(key) |
|
70 | self.get_mut().non_normal_entries_contains(key) | |
67 | } |
|
71 | } | |
68 |
|
72 | |||
69 | fn non_normal_entries_remove(&mut self, key: &HgPath) { |
|
73 | fn non_normal_entries_remove(&mut self, key: &HgPath) -> bool { | |
70 | self.get_mut().non_normal_entries_remove(key) |
|
74 | self.get_mut().non_normal_entries_remove(key) | |
71 | } |
|
75 | } | |
72 |
|
76 | |||
|
77 | fn non_normal_entries_add(&mut self, key: &HgPath) { | |||
|
78 | self.get_mut().non_normal_entries_add(key) | |||
|
79 | } | |||
|
80 | ||||
73 | fn non_normal_or_other_parent_paths( |
|
81 | fn non_normal_or_other_parent_paths( | |
74 | &mut self, |
|
82 | &mut self, | |
75 | ) -> Box<dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + '_> |
|
83 | ) -> Box<dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + '_> |
@@ -26,6 +26,12 b' py_class!(pub class NonNormalEntries |py' | |||||
26 | def remove(&self, key: PyObject) -> PyResult<PyObject> { |
|
26 | def remove(&self, key: PyObject) -> PyResult<PyObject> { | |
27 | self.dmap(py).non_normal_entries_remove(py, key) |
|
27 | self.dmap(py).non_normal_entries_remove(py, key) | |
28 | } |
|
28 | } | |
|
29 | def add(&self, key: PyObject) -> PyResult<PyObject> { | |||
|
30 | self.dmap(py).non_normal_entries_add(py, key) | |||
|
31 | } | |||
|
32 | def discard(&self, key: PyObject) -> PyResult<PyObject> { | |||
|
33 | self.dmap(py).non_normal_entries_discard(py, key) | |||
|
34 | } | |||
29 | def __richcmp__(&self, other: PyObject, op: CompareOp) -> PyResult<bool> { |
|
35 | def __richcmp__(&self, other: PyObject, op: CompareOp) -> PyResult<bool> { | |
30 | match op { |
|
36 | match op { | |
31 | CompareOp::Eq => self.is_equal_to(py, other), |
|
37 | CompareOp::Eq => self.is_equal_to(py, other), |
General Comments 0
You need to be logged in to leave comments.
Login now