Show More
@@ -661,24 +661,6 b' static PyObject *dirstate_item_get_remov' | |||
|
661 | 661 | } |
|
662 | 662 | }; |
|
663 | 663 | |
|
664 | static PyObject *dm_nonnormal(dirstateItemObject *self) | |
|
665 | { | |
|
666 | if ((dirstate_item_c_v1_state(self) != 'n') || | |
|
667 | (dirstate_item_c_v1_mtime(self) == ambiguous_time)) { | |
|
668 | Py_RETURN_TRUE; | |
|
669 | } else { | |
|
670 | Py_RETURN_FALSE; | |
|
671 | } | |
|
672 | }; | |
|
673 | static PyObject *dm_otherparent(dirstateItemObject *self) | |
|
674 | { | |
|
675 | if (dirstate_item_c_v1_mtime(self) == dirstate_v1_from_p2) { | |
|
676 | Py_RETURN_TRUE; | |
|
677 | } else { | |
|
678 | Py_RETURN_FALSE; | |
|
679 | } | |
|
680 | }; | |
|
681 | ||
|
682 | 664 | static PyGetSetDef dirstate_item_getset[] = { |
|
683 | 665 | {"mode", (getter)dirstate_item_get_mode, NULL, "mode", NULL}, |
|
684 | 666 | {"size", (getter)dirstate_item_get_size, NULL, "size", NULL}, |
@@ -693,8 +675,6 b' static PyGetSetDef dirstate_item_getset[' | |||
|
693 | 675 | "from_p2_removed", NULL}, |
|
694 | 676 | {"from_p2", (getter)dirstate_item_get_from_p2, NULL, "from_p2", NULL}, |
|
695 | 677 | {"removed", (getter)dirstate_item_get_removed, NULL, "removed", NULL}, |
|
696 | {"dm_nonnormal", (getter)dm_nonnormal, NULL, "dm_nonnormal", NULL}, | |
|
697 | {"dm_otherparent", (getter)dm_otherparent, NULL, "dm_otherparent", NULL}, | |
|
698 | 678 | {NULL} /* Sentinel */ |
|
699 | 679 | }; |
|
700 | 680 | |
@@ -831,70 +811,6 b' quit:' | |||
|
831 | 811 | } |
|
832 | 812 | |
|
833 | 813 | /* |
|
834 | * Build a set of non-normal and other parent entries from the dirstate dmap | |
|
835 | */ | |
|
836 | static PyObject *nonnormalotherparententries(PyObject *self, PyObject *args) | |
|
837 | { | |
|
838 | PyObject *dmap, *fname, *v; | |
|
839 | PyObject *nonnset = NULL, *otherpset = NULL, *result = NULL; | |
|
840 | Py_ssize_t pos; | |
|
841 | ||
|
842 | if (!PyArg_ParseTuple(args, "O!:nonnormalentries", &PyDict_Type, | |
|
843 | &dmap)) { | |
|
844 | goto bail; | |
|
845 | } | |
|
846 | ||
|
847 | nonnset = PySet_New(NULL); | |
|
848 | if (nonnset == NULL) { | |
|
849 | goto bail; | |
|
850 | } | |
|
851 | ||
|
852 | otherpset = PySet_New(NULL); | |
|
853 | if (otherpset == NULL) { | |
|
854 | goto bail; | |
|
855 | } | |
|
856 | ||
|
857 | pos = 0; | |
|
858 | while (PyDict_Next(dmap, &pos, &fname, &v)) { | |
|
859 | dirstateItemObject *t; | |
|
860 | if (!dirstate_tuple_check(v)) { | |
|
861 | PyErr_SetString(PyExc_TypeError, | |
|
862 | "expected a dirstate tuple"); | |
|
863 | goto bail; | |
|
864 | } | |
|
865 | t = (dirstateItemObject *)v; | |
|
866 | ||
|
867 | if (dirstate_item_c_from_p2(t)) { | |
|
868 | if (PySet_Add(otherpset, fname) == -1) { | |
|
869 | goto bail; | |
|
870 | } | |
|
871 | } | |
|
872 | if (!(t->flags & dirstate_flag_wc_tracked) || | |
|
873 | !(t->flags & | |
|
874 | (dirstate_flag_p1_tracked | dirstate_flag_p2_tracked)) || | |
|
875 | (t->flags & | |
|
876 | (dirstate_flag_possibly_dirty | dirstate_flag_merged))) { | |
|
877 | if (PySet_Add(nonnset, fname) == -1) { | |
|
878 | goto bail; | |
|
879 | } | |
|
880 | } | |
|
881 | } | |
|
882 | ||
|
883 | result = Py_BuildValue("(OO)", nonnset, otherpset); | |
|
884 | if (result == NULL) { | |
|
885 | goto bail; | |
|
886 | } | |
|
887 | Py_DECREF(nonnset); | |
|
888 | Py_DECREF(otherpset); | |
|
889 | return result; | |
|
890 | bail: | |
|
891 | Py_XDECREF(nonnset); | |
|
892 | Py_XDECREF(otherpset); | |
|
893 | Py_XDECREF(result); | |
|
894 | return NULL; | |
|
895 | } | |
|
896 | ||
|
897 | /* | |
|
898 | 814 | * Efficiently pack a dirstate object into its on-disk format. |
|
899 | 815 | */ |
|
900 | 816 | static PyObject *pack_dirstate(PyObject *self, PyObject *args) |
@@ -1226,9 +1142,6 b' PyObject *parse_index2(PyObject *self, P' | |||
|
1226 | 1142 | |
|
1227 | 1143 | static PyMethodDef methods[] = { |
|
1228 | 1144 | {"pack_dirstate", pack_dirstate, METH_VARARGS, "pack a dirstate\n"}, |
|
1229 | {"nonnormalotherparententries", nonnormalotherparententries, METH_VARARGS, | |
|
1230 | "create a set containing non-normal and other parent entries of given " | |
|
1231 | "dirstate\n"}, | |
|
1232 | 1145 | {"parse_dirstate", parse_dirstate, METH_VARARGS, "parse a dirstate\n"}, |
|
1233 | 1146 | {"parse_index2", (PyCFunction)parse_index2, METH_VARARGS | METH_KEYWORDS, |
|
1234 | 1147 | "parse a revlog index\n"}, |
@@ -62,12 +62,6 b' class dirstatemap(object):' | |||
|
62 | 62 | |
|
63 | 63 | The dirstate also provides the following views onto the state: |
|
64 | 64 | |
|
65 | - `nonnormalset` is a set of the filenames that have state other | |
|
66 | than 'normal', or are normal but have an mtime of -1 ('normallookup'). | |
|
67 | ||
|
68 | - `otherparentset` is a set of the filenames that are marked as coming | |
|
69 | from the second parent when the dirstate is currently being merged. | |
|
70 | ||
|
71 | 65 | - `filefoldmap` is a dict mapping normalized filenames to the denormalized |
|
72 | 66 | form that they appear as in the dirstate. |
|
73 | 67 | |
@@ -112,8 +106,6 b' class dirstatemap(object):' | |||
|
112 | 106 | util.clearcachedproperty(self, b"_alldirs") |
|
113 | 107 | util.clearcachedproperty(self, b"filefoldmap") |
|
114 | 108 | util.clearcachedproperty(self, b"dirfoldmap") |
|
115 | util.clearcachedproperty(self, b"nonnormalset") | |
|
116 | util.clearcachedproperty(self, b"otherparentset") | |
|
117 | 109 | |
|
118 | 110 | def items(self): |
|
119 | 111 | return pycompat.iteritems(self._map) |
@@ -185,7 +177,6 b' class dirstatemap(object):' | |||
|
185 | 177 | size = size & rangemask |
|
186 | 178 | entry.set_clean(mode, size, mtime) |
|
187 | 179 | self.copymap.pop(filename, None) |
|
188 | self.nonnormalset.discard(filename) | |
|
189 | 180 | |
|
190 | 181 | def reset_state( |
|
191 | 182 | self, |
@@ -218,7 +209,6 b' class dirstatemap(object):' | |||
|
218 | 209 | if not (p1_tracked or p2_tracked or wc_tracked): |
|
219 | 210 | old_entry = self._map.pop(filename, None) |
|
220 | 211 | self._dirs_decr(filename, old_entry=old_entry) |
|
221 | self.nonnormalset.discard(filename) | |
|
222 | 212 | self.copymap.pop(filename, None) |
|
223 | 213 | return |
|
224 | 214 | elif merged: |
@@ -271,14 +261,6 b' class dirstatemap(object):' | |||
|
271 | 261 | possibly_dirty=possibly_dirty, |
|
272 | 262 | parentfiledata=parentfiledata, |
|
273 | 263 | ) |
|
274 | if entry.dm_nonnormal: | |
|
275 | self.nonnormalset.add(filename) | |
|
276 | else: | |
|
277 | self.nonnormalset.discard(filename) | |
|
278 | if entry.dm_otherparent: | |
|
279 | self.otherparentset.add(filename) | |
|
280 | else: | |
|
281 | self.otherparentset.discard(filename) | |
|
282 | 264 | self._map[filename] = entry |
|
283 | 265 | |
|
284 | 266 | def set_tracked(self, filename): |
@@ -297,8 +279,6 b' class dirstatemap(object):' | |||
|
297 | 279 | parentfiledata=None, |
|
298 | 280 | ) |
|
299 | 281 | self._map[filename] = entry |
|
300 | if entry.dm_nonnormal: | |
|
301 | self.nonnormalset.add(filename) | |
|
302 | 282 | new = True |
|
303 | 283 | elif not entry.tracked: |
|
304 | 284 | self._dirs_incr(filename, entry) |
@@ -321,29 +301,11 b' class dirstatemap(object):' | |||
|
321 | 301 | if not entry.merged: |
|
322 | 302 | self.copymap.pop(f, None) |
|
323 | 303 | if entry.added: |
|
324 | self.nonnormalset.discard(f) | |
|
325 | 304 | self._map.pop(f, None) |
|
326 | 305 | else: |
|
327 | self.nonnormalset.add(f) | |
|
328 | if entry.from_p2: | |
|
329 | self.otherparentset.add(f) | |
|
330 | 306 | entry.set_untracked() |
|
331 | 307 | return True |
|
332 | 308 | |
|
333 | def nonnormalentries(self): | |
|
334 | '''Compute the nonnormal dirstate entries from the dmap''' | |
|
335 | try: | |
|
336 | return parsers.nonnormalotherparententries(self._map) | |
|
337 | except AttributeError: | |
|
338 | nonnorm = set() | |
|
339 | otherparent = set() | |
|
340 | for fname, e in pycompat.iteritems(self._map): | |
|
341 | if e.dm_nonnormal: | |
|
342 | nonnorm.add(fname) | |
|
343 | if e.from_p2: | |
|
344 | otherparent.add(fname) | |
|
345 | return nonnorm, otherparent | |
|
346 | ||
|
347 | 309 | @propertycache |
|
348 | 310 | def filefoldmap(self): |
|
349 | 311 | """Returns a dictionary mapping normalized case paths to their |
@@ -433,13 +395,7 b' class dirstatemap(object):' | |||
|
433 | 395 | self._dirtyparents = True |
|
434 | 396 | copies = {} |
|
435 | 397 | if fold_p2: |
|
436 | candidatefiles = self.non_normal_or_other_parent_paths() | |
|
437 | ||
|
438 | for f in candidatefiles: | |
|
439 | s = self.get(f) | |
|
440 | if s is None: | |
|
441 | continue | |
|
442 | ||
|
398 | for f, s in pycompat.iteritems(self._map): | |
|
443 | 399 | # Discard "merged" markers when moving away from a merge state |
|
444 | 400 | if s.merged or s.from_p2: |
|
445 | 401 | source = self.copymap.pop(f, None) |
@@ -504,22 +460,6 b' class dirstatemap(object):' | |||
|
504 | 460 | ) |
|
505 | 461 | st.close() |
|
506 | 462 | self._dirtyparents = False |
|
507 | self.nonnormalset, self.otherparentset = self.nonnormalentries() | |
|
508 | ||
|
509 | @propertycache | |
|
510 | def nonnormalset(self): | |
|
511 | nonnorm, otherparents = self.nonnormalentries() | |
|
512 | self.otherparentset = otherparents | |
|
513 | return nonnorm | |
|
514 | ||
|
515 | @propertycache | |
|
516 | def otherparentset(self): | |
|
517 | nonnorm, otherparents = self.nonnormalentries() | |
|
518 | self.nonnormalset = nonnorm | |
|
519 | return otherparents | |
|
520 | ||
|
521 | def non_normal_or_other_parent_paths(self): | |
|
522 | return self.nonnormalset.union(self.otherparentset) | |
|
523 | 463 | |
|
524 | 464 | @propertycache |
|
525 | 465 | def identity(self): |
@@ -643,7 +583,6 b' if rustmod is not None:' | |||
|
643 | 583 | elif (p1_tracked or p2_tracked) and not wc_tracked: |
|
644 | 584 | # XXX might be merged and removed ? |
|
645 | 585 | self[filename] = DirstateItem.from_v1_data(b'r', 0, 0, 0) |
|
646 | self.nonnormalset.add(filename) | |
|
647 | 586 | elif clean_p2 and wc_tracked: |
|
648 | 587 | if p1_tracked or self.get(filename) is not None: |
|
649 | 588 | # XXX the `self.get` call is catching some case in |
@@ -670,7 +609,6 b' if rustmod is not None:' | |||
|
670 | 609 | raise error.ProgrammingError(msg) |
|
671 | 610 | mode, size, mtime = parentfiledata |
|
672 | 611 | self.addfile(filename, mode=mode, size=size, mtime=mtime) |
|
673 | self.nonnormalset.discard(filename) | |
|
674 | 612 | else: |
|
675 | 613 | assert False, 'unreachable' |
|
676 | 614 | |
@@ -710,9 +648,6 b' if rustmod is not None:' | |||
|
710 | 648 | def removefile(self, *args, **kwargs): |
|
711 | 649 | return self._rustmap.removefile(*args, **kwargs) |
|
712 | 650 | |
|
713 | def nonnormalentries(self): | |
|
714 | return self._rustmap.nonnormalentries() | |
|
715 | ||
|
716 | 651 | def get(self, *args, **kwargs): |
|
717 | 652 | return self._rustmap.get(*args, **kwargs) |
|
718 | 653 | |
@@ -790,13 +725,17 b' if rustmod is not None:' | |||
|
790 | 725 | self._dirtyparents = True |
|
791 | 726 | copies = {} |
|
792 | 727 | if fold_p2: |
|
793 | candidatefiles = self.non_normal_or_other_parent_paths() | |
|
794 | ||
|
795 | for f in candidatefiles: | |
|
796 | s = self.get(f) | |
|
797 | if s is None: | |
|
798 |
|
|
|
799 | ||
|
728 | # Collect into an intermediate list to avoid a `RuntimeError` | |
|
729 | # exception due to mutation during iteration. | |
|
730 | # TODO: move this the whole loop to Rust where `iter_mut` | |
|
731 | # enables in-place mutation of elements of a collection while | |
|
732 | # iterating it, without mutating the collection itself. | |
|
733 | candidatefiles = [ | |
|
734 | (f, s) | |
|
735 | for f, s in self._rustmap.items() | |
|
736 | if s.merged or s.from_p2 | |
|
737 | ] | |
|
738 | for f, s in candidatefiles: | |
|
800 | 739 | # Discard "merged" markers when moving away from a merge state |
|
801 | 740 | if s.merged: |
|
802 | 741 | source = self.copymap.get(f) |
@@ -965,19 +904,6 b' if rustmod is not None:' | |||
|
965 | 904 | self._rustmap |
|
966 | 905 | return self.identity |
|
967 | 906 | |
|
968 | @property | |
|
969 | def nonnormalset(self): | |
|
970 | nonnorm = self._rustmap.non_normal_entries() | |
|
971 | return nonnorm | |
|
972 | ||
|
973 | @propertycache | |
|
974 | def otherparentset(self): | |
|
975 | otherparents = self._rustmap.other_parent_entries() | |
|
976 | return otherparents | |
|
977 | ||
|
978 | def non_normal_or_other_parent_paths(self): | |
|
979 | return self._rustmap.non_normal_or_other_parent_paths() | |
|
980 | ||
|
981 | 907 | @propertycache |
|
982 | 908 | def dirfoldmap(self): |
|
983 | 909 | f = {} |
@@ -361,22 +361,6 b' class DirstateItem(object):' | |||
|
361 | 361 | """ |
|
362 | 362 | return self.removed and self._merged |
|
363 | 363 | |
|
364 | @property | |
|
365 | def dm_nonnormal(self): | |
|
366 | """True is the entry is non-normal in the dirstatemap sense | |
|
367 | ||
|
368 | There is no reason for any code, but the dirstatemap one to use this. | |
|
369 | """ | |
|
370 | return self.v1_state() != b'n' or self.v1_mtime() == AMBIGUOUS_TIME | |
|
371 | ||
|
372 | @property | |
|
373 | def dm_otherparent(self): | |
|
374 | """True is the entry is `otherparent` in the dirstatemap sense | |
|
375 | ||
|
376 | There is no reason for any code, but the dirstatemap one to use this. | |
|
377 | """ | |
|
378 | return self.v1_size() == FROM_P2 | |
|
379 | ||
|
380 | 364 | def v1_state(self): |
|
381 | 365 | """return a "state" suitable for v1 serialization""" |
|
382 | 366 | if not (self._p1_tracked or self._p2_tracked or self._wc_tracked): |
@@ -6,6 +6,7 b'' | |||
|
6 | 6 | // GNU General Public License version 2 or any later version. |
|
7 | 7 | |
|
8 | 8 | use crate::dirstate::parsers::Timestamp; |
|
9 | use crate::errors::HgError; | |
|
9 | 10 | use crate::{ |
|
10 | 11 | dirstate::EntryState, |
|
11 | 12 | dirstate::SIZE_FROM_OTHER_PARENT, |
@@ -16,7 +17,6 b' use crate::{' | |||
|
16 | 17 | StateMap, |
|
17 | 18 | }; |
|
18 | 19 | use micro_timer::timed; |
|
19 | use std::collections::HashSet; | |
|
20 | 20 | use std::iter::FromIterator; |
|
21 | 21 | use std::ops::Deref; |
|
22 | 22 | |
@@ -26,8 +26,6 b' pub struct DirstateMap {' | |||
|
26 | 26 | pub copy_map: CopyMap, |
|
27 | 27 | pub dirs: Option<DirsMultiset>, |
|
28 | 28 | pub all_dirs: Option<DirsMultiset>, |
|
29 | non_normal_set: Option<HashSet<HgPathBuf>>, | |
|
30 | other_parent_set: Option<HashSet<HgPathBuf>>, | |
|
31 | 29 | } |
|
32 | 30 | |
|
33 | 31 | /// Should only really be used in python interface code, for clarity |
@@ -58,8 +56,6 b' impl DirstateMap {' | |||
|
58 | 56 | pub fn clear(&mut self) { |
|
59 | 57 | self.state_map = StateMap::default(); |
|
60 | 58 | self.copy_map.clear(); |
|
61 | self.non_normal_set = None; | |
|
62 | self.other_parent_set = None; | |
|
63 | 59 | } |
|
64 | 60 | |
|
65 | 61 | pub fn set_entry(&mut self, filename: &HgPath, entry: DirstateEntry) { |
@@ -84,18 +80,6 b' impl DirstateMap {' | |||
|
84 | 80 | } |
|
85 | 81 | } |
|
86 | 82 | self.state_map.insert(filename.to_owned(), entry.to_owned()); |
|
87 | ||
|
88 | if entry.is_non_normal() { | |
|
89 | self.get_non_normal_other_parent_entries() | |
|
90 | .0 | |
|
91 | .insert(filename.to_owned()); | |
|
92 | } | |
|
93 | ||
|
94 | if entry.is_from_other_parent() { | |
|
95 | self.get_non_normal_other_parent_entries() | |
|
96 | .1 | |
|
97 | .insert(filename.to_owned()); | |
|
98 | } | |
|
99 | 83 | Ok(()) |
|
100 | 84 | } |
|
101 | 85 | |
@@ -126,9 +110,6 b' impl DirstateMap {' | |||
|
126 | 110 | { |
|
127 | 111 | // other parent |
|
128 | 112 | size = SIZE_FROM_OTHER_PARENT; |
|
129 | self.get_non_normal_other_parent_entries() | |
|
130 | .1 | |
|
131 | .insert(filename.to_owned()); | |
|
132 | 113 | } |
|
133 | 114 | } |
|
134 | 115 | } |
@@ -148,9 +129,6 b' impl DirstateMap {' | |||
|
148 | 129 | |
|
149 | 130 | self.state_map |
|
150 | 131 | .insert(filename.to_owned(), DirstateEntry::new_removed(size)); |
|
151 | self.get_non_normal_other_parent_entries() | |
|
152 | .0 | |
|
153 | .insert(filename.to_owned()); | |
|
154 | 132 | Ok(()) |
|
155 | 133 | } |
|
156 | 134 | |
@@ -173,92 +151,11 b' impl DirstateMap {' | |||
|
173 | 151 | all_dirs.delete_path(filename)?; |
|
174 | 152 | } |
|
175 | 153 | } |
|
176 | self.get_non_normal_other_parent_entries() | |
|
177 | .0 | |
|
178 | .remove(filename); | |
|
179 | ||
|
180 | 154 | self.copy_map.remove(filename); |
|
181 | 155 | |
|
182 | 156 | Ok(()) |
|
183 | 157 | } |
|
184 | 158 | |
|
185 | pub fn non_normal_entries_remove( | |
|
186 | &mut self, | |
|
187 | key: impl AsRef<HgPath>, | |
|
188 | ) -> bool { | |
|
189 | self.get_non_normal_other_parent_entries() | |
|
190 | .0 | |
|
191 | .remove(key.as_ref()) | |
|
192 | } | |
|
193 | ||
|
194 | pub fn non_normal_entries_add(&mut self, key: impl AsRef<HgPath>) { | |
|
195 | self.get_non_normal_other_parent_entries() | |
|
196 | .0 | |
|
197 | .insert(key.as_ref().into()); | |
|
198 | } | |
|
199 | ||
|
200 | pub fn non_normal_entries_union( | |
|
201 | &mut self, | |
|
202 | other: HashSet<HgPathBuf>, | |
|
203 | ) -> Vec<HgPathBuf> { | |
|
204 | self.get_non_normal_other_parent_entries() | |
|
205 | .0 | |
|
206 | .union(&other) | |
|
207 | .map(ToOwned::to_owned) | |
|
208 | .collect() | |
|
209 | } | |
|
210 | ||
|
211 | pub fn get_non_normal_other_parent_entries( | |
|
212 | &mut self, | |
|
213 | ) -> (&mut HashSet<HgPathBuf>, &mut HashSet<HgPathBuf>) { | |
|
214 | self.set_non_normal_other_parent_entries(false); | |
|
215 | ( | |
|
216 | self.non_normal_set.as_mut().unwrap(), | |
|
217 | self.other_parent_set.as_mut().unwrap(), | |
|
218 | ) | |
|
219 | } | |
|
220 | ||
|
221 | /// Useful to get immutable references to those sets in contexts where | |
|
222 | /// you only have an immutable reference to the `DirstateMap`, like when | |
|
223 | /// sharing references with Python. | |
|
224 | /// | |
|
225 | /// TODO, get rid of this along with the other "setter/getter" stuff when | |
|
226 | /// a nice typestate plan is defined. | |
|
227 | /// | |
|
228 | /// # Panics | |
|
229 | /// | |
|
230 | /// Will panic if either set is `None`. | |
|
231 | pub fn get_non_normal_other_parent_entries_panic( | |
|
232 | &self, | |
|
233 | ) -> (&HashSet<HgPathBuf>, &HashSet<HgPathBuf>) { | |
|
234 | ( | |
|
235 | self.non_normal_set.as_ref().unwrap(), | |
|
236 | self.other_parent_set.as_ref().unwrap(), | |
|
237 | ) | |
|
238 | } | |
|
239 | ||
|
240 | pub fn set_non_normal_other_parent_entries(&mut self, force: bool) { | |
|
241 | if !force | |
|
242 | && self.non_normal_set.is_some() | |
|
243 | && self.other_parent_set.is_some() | |
|
244 | { | |
|
245 | return; | |
|
246 | } | |
|
247 | let mut non_normal = HashSet::new(); | |
|
248 | let mut other_parent = HashSet::new(); | |
|
249 | ||
|
250 | for (filename, entry) in self.state_map.iter() { | |
|
251 | if entry.is_non_normal() { | |
|
252 | non_normal.insert(filename.to_owned()); | |
|
253 | } | |
|
254 | if entry.is_from_other_parent() { | |
|
255 | other_parent.insert(filename.to_owned()); | |
|
256 | } | |
|
257 | } | |
|
258 | self.non_normal_set = Some(non_normal); | |
|
259 | self.other_parent_set = Some(other_parent); | |
|
260 | } | |
|
261 | ||
|
262 | 159 | /// Both of these setters and their uses appear to be the simplest way to |
|
263 | 160 | /// emulate a Python lazy property, but it is ugly and unidiomatic. |
|
264 | 161 | /// TODO One day, rewriting this struct using the typestate might be a |
@@ -326,12 +223,8 b' impl DirstateMap {' | |||
|
326 | 223 | &mut self, |
|
327 | 224 | parents: DirstateParents, |
|
328 | 225 | now: Timestamp, |
|
329 |
) -> Result<Vec<u8>, |
|
|
330 | let packed = | |
|
331 | pack_dirstate(&mut self.state_map, &self.copy_map, parents, now)?; | |
|
332 | ||
|
333 | self.set_non_normal_other_parent_entries(true); | |
|
334 | Ok(packed) | |
|
226 | ) -> Result<Vec<u8>, HgError> { | |
|
227 | pack_dirstate(&mut self.state_map, &self.copy_map, parents, now) | |
|
335 | 228 | } |
|
336 | 229 | } |
|
337 | 230 | |
@@ -366,49 +259,5 b' mod tests {' | |||
|
366 | 259 | .unwrap(); |
|
367 | 260 | |
|
368 | 261 | assert_eq!(1, map.len()); |
|
369 | assert_eq!(0, map.get_non_normal_other_parent_entries().0.len()); | |
|
370 | assert_eq!(0, map.get_non_normal_other_parent_entries().1.len()); | |
|
371 | } | |
|
372 | ||
|
373 | #[test] | |
|
374 | fn test_non_normal_other_parent_entries() { | |
|
375 | let mut map: DirstateMap = [ | |
|
376 | (b"f1", (EntryState::Removed, 1337, 1337, 1337)), | |
|
377 | (b"f2", (EntryState::Normal, 1337, 1337, -1)), | |
|
378 | (b"f3", (EntryState::Normal, 1337, 1337, 1337)), | |
|
379 | (b"f4", (EntryState::Normal, 1337, -2, 1337)), | |
|
380 | (b"f5", (EntryState::Added, 1337, 1337, 1337)), | |
|
381 | (b"f6", (EntryState::Added, 1337, 1337, -1)), | |
|
382 | (b"f7", (EntryState::Merged, 1337, 1337, -1)), | |
|
383 | (b"f8", (EntryState::Merged, 1337, 1337, 1337)), | |
|
384 | (b"f9", (EntryState::Merged, 1337, -2, 1337)), | |
|
385 | (b"fa", (EntryState::Added, 1337, -2, 1337)), | |
|
386 | (b"fb", (EntryState::Removed, 1337, -2, 1337)), | |
|
387 | ] | |
|
388 | .iter() | |
|
389 | .map(|(fname, (state, mode, size, mtime))| { | |
|
390 | ( | |
|
391 | HgPathBuf::from_bytes(fname.as_ref()), | |
|
392 | DirstateEntry::from_v1_data(*state, *mode, *size, *mtime), | |
|
393 | ) | |
|
394 | }) | |
|
395 | .collect(); | |
|
396 | ||
|
397 | let mut non_normal = [ | |
|
398 | b"f1", b"f2", b"f4", b"f5", b"f6", b"f7", b"f8", b"f9", b"fa", | |
|
399 | b"fb", | |
|
400 | ] | |
|
401 | .iter() | |
|
402 | .map(|x| HgPathBuf::from_bytes(x.as_ref())) | |
|
403 | .collect(); | |
|
404 | ||
|
405 | let mut other_parent = HashSet::new(); | |
|
406 | other_parent.insert(HgPathBuf::from_bytes(b"f4")); | |
|
407 | let entries = map.get_non_normal_other_parent_entries(); | |
|
408 | ||
|
409 | assert_eq!( | |
|
410 | (&mut non_normal, &mut other_parent), | |
|
411 | (entries.0, entries.1) | |
|
412 | ); | |
|
413 | 262 | } |
|
414 | 263 | } |
@@ -294,11 +294,7 b' impl DirstateEntry {' | |||
|
294 | 294 | (self.state().into(), self.mode(), self.size(), self.mtime()) |
|
295 | 295 | } |
|
296 | 296 | |
|
297 |
pub fn is_ |
|
|
298 | self.state() != EntryState::Normal || self.mtime() == MTIME_UNSET | |
|
299 | } | |
|
300 | ||
|
301 | pub fn is_from_other_parent(&self) -> bool { | |
|
297 | pub(crate) fn is_from_other_parent(&self) -> bool { | |
|
302 | 298 | self.state() == EntryState::Normal |
|
303 | 299 | && self.size() == SIZE_FROM_OTHER_PARENT |
|
304 | 300 | } |
@@ -701,27 +701,6 b" impl<'on_disk> DirstateMap<'on_disk> {" | |||
|
701 | 701 | Ok(()) |
|
702 | 702 | } |
|
703 | 703 | |
|
704 | /// Return a faillilble iterator of full paths of nodes that have an | |
|
705 | /// `entry` for which the given `predicate` returns true. | |
|
706 | /// | |
|
707 | /// Fallibility means that each iterator item is a `Result`, which may | |
|
708 | /// indicate a parse error of the on-disk dirstate-v2 format. Such errors | |
|
709 | /// should only happen if Mercurial is buggy or a repository is corrupted. | |
|
710 | fn filter_full_paths<'tree>( | |
|
711 | &'tree self, | |
|
712 | predicate: impl Fn(&DirstateEntry) -> bool + 'tree, | |
|
713 | ) -> impl Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + 'tree | |
|
714 | { | |
|
715 | filter_map_results(self.iter_nodes(), move |node| { | |
|
716 | if let Some(entry) = node.entry()? { | |
|
717 | if predicate(&entry) { | |
|
718 | return Ok(Some(node.full_path(self.on_disk)?)); | |
|
719 | } | |
|
720 | } | |
|
721 | Ok(None) | |
|
722 | }) | |
|
723 | } | |
|
724 | ||
|
725 | 704 | fn count_dropped_path(unreachable_bytes: &mut u32, path: &Cow<HgPath>) { |
|
726 | 705 | if let Cow::Borrowed(path) = path { |
|
727 | 706 | *unreachable_bytes += path.len() as u32 |
@@ -917,69 +896,6 b" impl<'on_disk> super::dispatch::Dirstate" | |||
|
917 | 896 | Ok(()) |
|
918 | 897 | } |
|
919 | 898 | |
|
920 | fn non_normal_entries_contains( | |
|
921 | &mut self, | |
|
922 | key: &HgPath, | |
|
923 | ) -> Result<bool, DirstateV2ParseError> { | |
|
924 | Ok(if let Some(node) = self.get_node(key)? { | |
|
925 | node.entry()?.map_or(false, |entry| entry.is_non_normal()) | |
|
926 | } else { | |
|
927 | false | |
|
928 | }) | |
|
929 | } | |
|
930 | ||
|
931 | fn non_normal_entries_remove(&mut self, key: &HgPath) -> bool { | |
|
932 | // Do nothing, this `DirstateMap` does not have a separate "non normal | |
|
933 | // entries" set that need to be kept up to date. | |
|
934 | if let Ok(Some(v)) = self.get(key) { | |
|
935 | return v.is_non_normal(); | |
|
936 | } | |
|
937 | false | |
|
938 | } | |
|
939 | ||
|
940 | fn non_normal_entries_add(&mut self, _key: &HgPath) { | |
|
941 | // Do nothing, this `DirstateMap` does not have a separate "non normal | |
|
942 | // entries" set that need to be kept up to date | |
|
943 | } | |
|
944 | ||
|
945 | fn non_normal_or_other_parent_paths( | |
|
946 | &mut self, | |
|
947 | ) -> Box<dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + '_> | |
|
948 | { | |
|
949 | Box::new(self.filter_full_paths(|entry| { | |
|
950 | entry.is_non_normal() || entry.is_from_other_parent() | |
|
951 | })) | |
|
952 | } | |
|
953 | ||
|
954 | fn set_non_normal_other_parent_entries(&mut self, _force: bool) { | |
|
955 | // Do nothing, this `DirstateMap` does not have a separate "non normal | |
|
956 | // entries" and "from other parent" sets that need to be recomputed | |
|
957 | } | |
|
958 | ||
|
959 | fn iter_non_normal_paths( | |
|
960 | &mut self, | |
|
961 | ) -> Box< | |
|
962 | dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_, | |
|
963 | > { | |
|
964 | self.iter_non_normal_paths_panic() | |
|
965 | } | |
|
966 | ||
|
967 | fn iter_non_normal_paths_panic( | |
|
968 | &self, | |
|
969 | ) -> Box< | |
|
970 | dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_, | |
|
971 | > { | |
|
972 | Box::new(self.filter_full_paths(|entry| entry.is_non_normal())) | |
|
973 | } | |
|
974 | ||
|
975 | fn iter_other_parent_paths( | |
|
976 | &mut self, | |
|
977 | ) -> Box< | |
|
978 | dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_, | |
|
979 | > { | |
|
980 | Box::new(self.filter_full_paths(|entry| entry.is_from_other_parent())) | |
|
981 | } | |
|
982 | ||
|
983 | 899 | fn has_tracked_dir( |
|
984 | 900 | &mut self, |
|
985 | 901 | directory: &HgPath, |
@@ -67,82 +67,6 b' pub trait DirstateMapMethods {' | |||
|
67 | 67 | filename: &HgPath, |
|
68 | 68 | ) -> Result<(), DirstateError>; |
|
69 | 69 | |
|
70 | /// Return whether the map has an "non-normal" entry for the given | |
|
71 | /// filename. That is, any entry with a `state` other than | |
|
72 | /// `EntryState::Normal` or with an ambiguous `mtime`. | |
|
73 | fn non_normal_entries_contains( | |
|
74 | &mut self, | |
|
75 | key: &HgPath, | |
|
76 | ) -> Result<bool, DirstateV2ParseError>; | |
|
77 | ||
|
78 | /// Mark the given path as "normal" file. This is only relevant in the flat | |
|
79 | /// dirstate map where there is a separate `HashSet` that needs to be kept | |
|
80 | /// up to date. | |
|
81 | /// Returns whether the key was present in the set. | |
|
82 | fn non_normal_entries_remove(&mut self, key: &HgPath) -> bool; | |
|
83 | ||
|
84 | /// Mark the given path as "non-normal" file. | |
|
85 | /// This is only relevant in the flat dirstate map where there is a | |
|
86 | /// separate `HashSet` that needs to be kept up to date. | |
|
87 | fn non_normal_entries_add(&mut self, key: &HgPath); | |
|
88 | ||
|
89 | /// Return an iterator of paths whose respective entry are either | |
|
90 | /// "non-normal" (see `non_normal_entries_contains`) or "from other | |
|
91 | /// parent". | |
|
92 | /// | |
|
93 | /// If that information is cached, create the cache as needed. | |
|
94 | /// | |
|
95 | /// "From other parent" is defined as `state == Normal && size == -2`. | |
|
96 | /// | |
|
97 | /// Because parse errors can happen during iteration, the iterated items | |
|
98 | /// are `Result`s. | |
|
99 | fn non_normal_or_other_parent_paths( | |
|
100 | &mut self, | |
|
101 | ) -> Box<dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + '_>; | |
|
102 | ||
|
103 | /// Create the cache for `non_normal_or_other_parent_paths` if needed. | |
|
104 | /// | |
|
105 | /// If `force` is true, the cache is re-created even if it already exists. | |
|
106 | fn set_non_normal_other_parent_entries(&mut self, force: bool); | |
|
107 | ||
|
108 | /// Return an iterator of paths whose respective entry are "non-normal" | |
|
109 | /// (see `non_normal_entries_contains`). | |
|
110 | /// | |
|
111 | /// If that information is cached, create the cache as needed. | |
|
112 | /// | |
|
113 | /// Because parse errors can happen during iteration, the iterated items | |
|
114 | /// are `Result`s. | |
|
115 | fn iter_non_normal_paths( | |
|
116 | &mut self, | |
|
117 | ) -> Box< | |
|
118 | dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_, | |
|
119 | >; | |
|
120 | ||
|
121 | /// Same as `iter_non_normal_paths`, but takes `&self` instead of `&mut | |
|
122 | /// self`. | |
|
123 | /// | |
|
124 | /// Panics if a cache is necessary but does not exist yet. | |
|
125 | fn iter_non_normal_paths_panic( | |
|
126 | &self, | |
|
127 | ) -> Box< | |
|
128 | dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_, | |
|
129 | >; | |
|
130 | ||
|
131 | /// Return an iterator of paths whose respective entry are "from other | |
|
132 | /// parent". | |
|
133 | /// | |
|
134 | /// If that information is cached, create the cache as needed. | |
|
135 | /// | |
|
136 | /// "From other parent" is defined as `state == Normal && size == -2`. | |
|
137 | /// | |
|
138 | /// Because parse errors can happen during iteration, the iterated items | |
|
139 | /// are `Result`s. | |
|
140 | fn iter_other_parent_paths( | |
|
141 | &mut self, | |
|
142 | ) -> Box< | |
|
143 | dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_, | |
|
144 | >; | |
|
145 | ||
|
146 | 70 | /// Returns whether the sub-tree rooted at the given directory contains any |
|
147 | 71 | /// tracked file. |
|
148 | 72 | /// |
@@ -330,66 +254,6 b' impl DirstateMapMethods for DirstateMap ' | |||
|
330 | 254 | self.drop_entry_and_copy_source(filename) |
|
331 | 255 | } |
|
332 | 256 | |
|
333 | fn non_normal_entries_contains( | |
|
334 | &mut self, | |
|
335 | key: &HgPath, | |
|
336 | ) -> Result<bool, DirstateV2ParseError> { | |
|
337 | let (non_normal, _other_parent) = | |
|
338 | self.get_non_normal_other_parent_entries(); | |
|
339 | Ok(non_normal.contains(key)) | |
|
340 | } | |
|
341 | ||
|
342 | fn non_normal_entries_remove(&mut self, key: &HgPath) -> bool { | |
|
343 | self.non_normal_entries_remove(key) | |
|
344 | } | |
|
345 | ||
|
346 | fn non_normal_entries_add(&mut self, key: &HgPath) { | |
|
347 | self.non_normal_entries_add(key) | |
|
348 | } | |
|
349 | ||
|
350 | fn non_normal_or_other_parent_paths( | |
|
351 | &mut self, | |
|
352 | ) -> Box<dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + '_> | |
|
353 | { | |
|
354 | let (non_normal, other_parent) = | |
|
355 | self.get_non_normal_other_parent_entries(); | |
|
356 | Box::new(non_normal.union(other_parent).map(|p| Ok(&**p))) | |
|
357 | } | |
|
358 | ||
|
359 | fn set_non_normal_other_parent_entries(&mut self, force: bool) { | |
|
360 | self.set_non_normal_other_parent_entries(force) | |
|
361 | } | |
|
362 | ||
|
363 | fn iter_non_normal_paths( | |
|
364 | &mut self, | |
|
365 | ) -> Box< | |
|
366 | dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_, | |
|
367 | > { | |
|
368 | let (non_normal, _other_parent) = | |
|
369 | self.get_non_normal_other_parent_entries(); | |
|
370 | Box::new(non_normal.iter().map(|p| Ok(&**p))) | |
|
371 | } | |
|
372 | ||
|
373 | fn iter_non_normal_paths_panic( | |
|
374 | &self, | |
|
375 | ) -> Box< | |
|
376 | dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_, | |
|
377 | > { | |
|
378 | let (non_normal, _other_parent) = | |
|
379 | self.get_non_normal_other_parent_entries_panic(); | |
|
380 | Box::new(non_normal.iter().map(|p| Ok(&**p))) | |
|
381 | } | |
|
382 | ||
|
383 | fn iter_other_parent_paths( | |
|
384 | &mut self, | |
|
385 | ) -> Box< | |
|
386 | dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_, | |
|
387 | > { | |
|
388 | let (_non_normal, other_parent) = | |
|
389 | self.get_non_normal_other_parent_entries(); | |
|
390 | Box::new(other_parent.iter().map(|p| Ok(&**p))) | |
|
391 | } | |
|
392 | ||
|
393 | 257 | fn has_tracked_dir( |
|
394 | 258 | &mut self, |
|
395 | 259 | directory: &HgPath, |
@@ -406,7 +270,7 b' impl DirstateMapMethods for DirstateMap ' | |||
|
406 | 270 | parents: DirstateParents, |
|
407 | 271 | now: Timestamp, |
|
408 | 272 | ) -> Result<Vec<u8>, DirstateError> { |
|
409 | self.pack(parents, now) | |
|
273 | Ok(self.pack(parents, now)?) | |
|
410 | 274 | } |
|
411 | 275 | |
|
412 | 276 | fn pack_v2( |
@@ -51,56 +51,6 b' impl DirstateMapMethods for OwningDirsta' | |||
|
51 | 51 | self.get_mut().drop_entry_and_copy_source(filename) |
|
52 | 52 | } |
|
53 | 53 | |
|
54 | fn non_normal_entries_contains( | |
|
55 | &mut self, | |
|
56 | key: &HgPath, | |
|
57 | ) -> Result<bool, DirstateV2ParseError> { | |
|
58 | self.get_mut().non_normal_entries_contains(key) | |
|
59 | } | |
|
60 | ||
|
61 | fn non_normal_entries_remove(&mut self, key: &HgPath) -> bool { | |
|
62 | self.get_mut().non_normal_entries_remove(key) | |
|
63 | } | |
|
64 | ||
|
65 | fn non_normal_entries_add(&mut self, key: &HgPath) { | |
|
66 | self.get_mut().non_normal_entries_add(key) | |
|
67 | } | |
|
68 | ||
|
69 | fn non_normal_or_other_parent_paths( | |
|
70 | &mut self, | |
|
71 | ) -> Box<dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + '_> | |
|
72 | { | |
|
73 | self.get_mut().non_normal_or_other_parent_paths() | |
|
74 | } | |
|
75 | ||
|
76 | fn set_non_normal_other_parent_entries(&mut self, force: bool) { | |
|
77 | self.get_mut().set_non_normal_other_parent_entries(force) | |
|
78 | } | |
|
79 | ||
|
80 | fn iter_non_normal_paths( | |
|
81 | &mut self, | |
|
82 | ) -> Box< | |
|
83 | dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_, | |
|
84 | > { | |
|
85 | self.get_mut().iter_non_normal_paths() | |
|
86 | } | |
|
87 | ||
|
88 | fn iter_non_normal_paths_panic( | |
|
89 | &self, | |
|
90 | ) -> Box< | |
|
91 | dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_, | |
|
92 | > { | |
|
93 | self.get().iter_non_normal_paths_panic() | |
|
94 | } | |
|
95 | ||
|
96 | fn iter_other_parent_paths( | |
|
97 | &mut self, | |
|
98 | ) -> Box< | |
|
99 | dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_, | |
|
100 | > { | |
|
101 | self.get_mut().iter_other_parent_paths() | |
|
102 | } | |
|
103 | ||
|
104 | 54 | fn has_tracked_dir( |
|
105 | 55 | &mut self, |
|
106 | 56 | directory: &HgPath, |
@@ -13,7 +13,6 b' mod copymap;' | |||
|
13 | 13 | mod dirs_multiset; |
|
14 | 14 | mod dirstate_map; |
|
15 | 15 | mod item; |
|
16 | mod non_normal_entries; | |
|
17 | 16 | mod status; |
|
18 | 17 | use self::item::DirstateItem; |
|
19 | 18 | use crate::{ |
@@ -13,16 +13,12 b' use std::convert::TryInto;' | |||
|
13 | 13 | |
|
14 | 14 | use cpython::{ |
|
15 | 15 | exc, PyBool, PyBytes, PyClone, PyDict, PyErr, PyList, PyNone, PyObject, |
|
16 |
PyResult |
|
|
17 | UnsafePyLeaked, | |
|
16 | PyResult, Python, PythonObject, ToPyObject, UnsafePyLeaked, | |
|
18 | 17 | }; |
|
19 | 18 | |
|
20 | 19 | use crate::{ |
|
21 | 20 | dirstate::copymap::{CopyMap, CopyMapItemsIterator, CopyMapKeysIterator}, |
|
22 | 21 | dirstate::item::DirstateItem, |
|
23 | dirstate::non_normal_entries::{ | |
|
24 | NonNormalEntries, NonNormalEntriesIterator, | |
|
25 | }, | |
|
26 | 22 | pybytes_deref::PyBytesDeref, |
|
27 | 23 | }; |
|
28 | 24 | use hg::{ |
@@ -185,100 +181,6 b' py_class!(pub class DirstateMap |py| {' | |||
|
185 | 181 | Ok(PyNone) |
|
186 | 182 | } |
|
187 | 183 | |
|
188 | def other_parent_entries(&self) -> PyResult<PyObject> { | |
|
189 | let mut inner_shared = self.inner(py).borrow_mut(); | |
|
190 | let set = PySet::empty(py)?; | |
|
191 | for path in inner_shared.iter_other_parent_paths() { | |
|
192 | let path = path.map_err(|e| v2_error(py, e))?; | |
|
193 | set.add(py, PyBytes::new(py, path.as_bytes()))?; | |
|
194 | } | |
|
195 | Ok(set.into_object()) | |
|
196 | } | |
|
197 | ||
|
198 | def non_normal_entries(&self) -> PyResult<NonNormalEntries> { | |
|
199 | NonNormalEntries::from_inner(py, self.clone_ref(py)) | |
|
200 | } | |
|
201 | ||
|
202 | def non_normal_entries_contains(&self, key: PyObject) -> PyResult<bool> { | |
|
203 | let key = key.extract::<PyBytes>(py)?; | |
|
204 | self.inner(py) | |
|
205 | .borrow_mut() | |
|
206 | .non_normal_entries_contains(HgPath::new(key.data(py))) | |
|
207 | .map_err(|e| v2_error(py, e)) | |
|
208 | } | |
|
209 | ||
|
210 | def non_normal_entries_display(&self) -> PyResult<PyString> { | |
|
211 | let mut inner = self.inner(py).borrow_mut(); | |
|
212 | let paths = inner | |
|
213 | .iter_non_normal_paths() | |
|
214 | .collect::<Result<Vec<_>, _>>() | |
|
215 | .map_err(|e| v2_error(py, e))?; | |
|
216 | let formatted = format!("NonNormalEntries: {}", hg::utils::join_display(paths, ", ")); | |
|
217 | Ok(PyString::new(py, &formatted)) | |
|
218 | } | |
|
219 | ||
|
220 | def non_normal_entries_remove(&self, key: PyObject) -> PyResult<PyObject> { | |
|
221 | let key = key.extract::<PyBytes>(py)?; | |
|
222 | let key = key.data(py); | |
|
223 | let was_present = self | |
|
224 | .inner(py) | |
|
225 | .borrow_mut() | |
|
226 | .non_normal_entries_remove(HgPath::new(key)); | |
|
227 | if !was_present { | |
|
228 | let msg = String::from_utf8_lossy(key); | |
|
229 | Err(PyErr::new::<exc::KeyError, _>(py, msg)) | |
|
230 | } else { | |
|
231 | Ok(py.None()) | |
|
232 | } | |
|
233 | } | |
|
234 | ||
|
235 | def non_normal_entries_discard(&self, key: PyObject) -> PyResult<PyObject> | |
|
236 | { | |
|
237 | let key = key.extract::<PyBytes>(py)?; | |
|
238 | self | |
|
239 | .inner(py) | |
|
240 | .borrow_mut() | |
|
241 | .non_normal_entries_remove(HgPath::new(key.data(py))); | |
|
242 | Ok(py.None()) | |
|
243 | } | |
|
244 | ||
|
245 | def non_normal_entries_add(&self, key: PyObject) -> PyResult<PyObject> { | |
|
246 | let key = key.extract::<PyBytes>(py)?; | |
|
247 | self | |
|
248 | .inner(py) | |
|
249 | .borrow_mut() | |
|
250 | .non_normal_entries_add(HgPath::new(key.data(py))); | |
|
251 | Ok(py.None()) | |
|
252 | } | |
|
253 | ||
|
254 | def non_normal_or_other_parent_paths(&self) -> PyResult<PyList> { | |
|
255 | let mut inner = self.inner(py).borrow_mut(); | |
|
256 | ||
|
257 | let ret = PyList::new(py, &[]); | |
|
258 | for filename in inner.non_normal_or_other_parent_paths() { | |
|
259 | let filename = filename.map_err(|e| v2_error(py, e))?; | |
|
260 | let as_pystring = PyBytes::new(py, filename.as_bytes()); | |
|
261 | ret.append(py, as_pystring.into_object()); | |
|
262 | } | |
|
263 | Ok(ret) | |
|
264 | } | |
|
265 | ||
|
266 | def non_normal_entries_iter(&self) -> PyResult<NonNormalEntriesIterator> { | |
|
267 | // Make sure the sets are defined before we no longer have a mutable | |
|
268 | // reference to the dmap. | |
|
269 | self.inner(py) | |
|
270 | .borrow_mut() | |
|
271 | .set_non_normal_other_parent_entries(false); | |
|
272 | ||
|
273 | let leaked_ref = self.inner(py).leak_immutable(); | |
|
274 | ||
|
275 | NonNormalEntriesIterator::from_inner(py, unsafe { | |
|
276 | leaked_ref.map(py, |o| { | |
|
277 | o.iter_non_normal_paths_panic() | |
|
278 | }) | |
|
279 | }) | |
|
280 | } | |
|
281 | ||
|
282 | 184 | def hastrackeddir(&self, d: PyObject) -> PyResult<PyBool> { |
|
283 | 185 | let d = d.extract::<PyBytes>(py)?; |
|
284 | 186 | Ok(self.inner(py).borrow_mut() |
@@ -95,16 +95,6 b' py_class!(pub class DirstateItem |py| {' | |||
|
95 | 95 | Ok(self.entry(py).get().from_p2_removed()) |
|
96 | 96 | } |
|
97 | 97 | |
|
98 | @property | |
|
99 | def dm_nonnormal(&self) -> PyResult<bool> { | |
|
100 | Ok(self.entry(py).get().is_non_normal()) | |
|
101 | } | |
|
102 | ||
|
103 | @property | |
|
104 | def dm_otherparent(&self) -> PyResult<bool> { | |
|
105 | Ok(self.entry(py).get().is_from_other_parent()) | |
|
106 | } | |
|
107 | ||
|
108 | 98 | def v1_state(&self) -> PyResult<PyBytes> { |
|
109 | 99 | let (state, _mode, _size, _mtime) = self.entry(py).get().v1_data(); |
|
110 | 100 | let state_byte: u8 = state.into(); |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now