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 | static PyGetSetDef dirstate_item_getset[] = { |
|
664 | static PyGetSetDef dirstate_item_getset[] = { | |
683 | {"mode", (getter)dirstate_item_get_mode, NULL, "mode", NULL}, |
|
665 | {"mode", (getter)dirstate_item_get_mode, NULL, "mode", NULL}, | |
684 | {"size", (getter)dirstate_item_get_size, NULL, "size", NULL}, |
|
666 | {"size", (getter)dirstate_item_get_size, NULL, "size", NULL}, | |
@@ -693,8 +675,6 b' static PyGetSetDef dirstate_item_getset[' | |||||
693 | "from_p2_removed", NULL}, |
|
675 | "from_p2_removed", NULL}, | |
694 | {"from_p2", (getter)dirstate_item_get_from_p2, NULL, "from_p2", NULL}, |
|
676 | {"from_p2", (getter)dirstate_item_get_from_p2, NULL, "from_p2", NULL}, | |
695 | {"removed", (getter)dirstate_item_get_removed, NULL, "removed", NULL}, |
|
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 | {NULL} /* Sentinel */ |
|
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 | * Efficiently pack a dirstate object into its on-disk format. |
|
814 | * Efficiently pack a dirstate object into its on-disk format. | |
899 | */ |
|
815 | */ | |
900 | static PyObject *pack_dirstate(PyObject *self, PyObject *args) |
|
816 | static PyObject *pack_dirstate(PyObject *self, PyObject *args) | |
@@ -1226,9 +1142,6 b' PyObject *parse_index2(PyObject *self, P' | |||||
1226 |
|
1142 | |||
1227 | static PyMethodDef methods[] = { |
|
1143 | static PyMethodDef methods[] = { | |
1228 | {"pack_dirstate", pack_dirstate, METH_VARARGS, "pack a dirstate\n"}, |
|
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 | {"parse_dirstate", parse_dirstate, METH_VARARGS, "parse a dirstate\n"}, |
|
1145 | {"parse_dirstate", parse_dirstate, METH_VARARGS, "parse a dirstate\n"}, | |
1233 | {"parse_index2", (PyCFunction)parse_index2, METH_VARARGS | METH_KEYWORDS, |
|
1146 | {"parse_index2", (PyCFunction)parse_index2, METH_VARARGS | METH_KEYWORDS, | |
1234 | "parse a revlog index\n"}, |
|
1147 | "parse a revlog index\n"}, |
@@ -62,12 +62,6 b' class dirstatemap(object):' | |||||
62 |
|
62 | |||
63 | The dirstate also provides the following views onto the state: |
|
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 | - `filefoldmap` is a dict mapping normalized filenames to the denormalized |
|
65 | - `filefoldmap` is a dict mapping normalized filenames to the denormalized | |
72 | form that they appear as in the dirstate. |
|
66 | form that they appear as in the dirstate. | |
73 |
|
67 | |||
@@ -112,8 +106,6 b' class dirstatemap(object):' | |||||
112 | util.clearcachedproperty(self, b"_alldirs") |
|
106 | util.clearcachedproperty(self, b"_alldirs") | |
113 | util.clearcachedproperty(self, b"filefoldmap") |
|
107 | util.clearcachedproperty(self, b"filefoldmap") | |
114 | util.clearcachedproperty(self, b"dirfoldmap") |
|
108 | util.clearcachedproperty(self, b"dirfoldmap") | |
115 | util.clearcachedproperty(self, b"nonnormalset") |
|
|||
116 | util.clearcachedproperty(self, b"otherparentset") |
|
|||
117 |
|
109 | |||
118 | def items(self): |
|
110 | def items(self): | |
119 | return pycompat.iteritems(self._map) |
|
111 | return pycompat.iteritems(self._map) | |
@@ -185,7 +177,6 b' class dirstatemap(object):' | |||||
185 | size = size & rangemask |
|
177 | size = size & rangemask | |
186 | entry.set_clean(mode, size, mtime) |
|
178 | entry.set_clean(mode, size, mtime) | |
187 | self.copymap.pop(filename, None) |
|
179 | self.copymap.pop(filename, None) | |
188 | self.nonnormalset.discard(filename) |
|
|||
189 |
|
180 | |||
190 | def reset_state( |
|
181 | def reset_state( | |
191 | self, |
|
182 | self, | |
@@ -218,7 +209,6 b' class dirstatemap(object):' | |||||
218 | if not (p1_tracked or p2_tracked or wc_tracked): |
|
209 | if not (p1_tracked or p2_tracked or wc_tracked): | |
219 | old_entry = self._map.pop(filename, None) |
|
210 | old_entry = self._map.pop(filename, None) | |
220 | self._dirs_decr(filename, old_entry=old_entry) |
|
211 | self._dirs_decr(filename, old_entry=old_entry) | |
221 | self.nonnormalset.discard(filename) |
|
|||
222 | self.copymap.pop(filename, None) |
|
212 | self.copymap.pop(filename, None) | |
223 | return |
|
213 | return | |
224 | elif merged: |
|
214 | elif merged: | |
@@ -271,14 +261,6 b' class dirstatemap(object):' | |||||
271 | possibly_dirty=possibly_dirty, |
|
261 | possibly_dirty=possibly_dirty, | |
272 | parentfiledata=parentfiledata, |
|
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 | self._map[filename] = entry |
|
264 | self._map[filename] = entry | |
283 |
|
265 | |||
284 | def set_tracked(self, filename): |
|
266 | def set_tracked(self, filename): | |
@@ -297,8 +279,6 b' class dirstatemap(object):' | |||||
297 | parentfiledata=None, |
|
279 | parentfiledata=None, | |
298 | ) |
|
280 | ) | |
299 | self._map[filename] = entry |
|
281 | self._map[filename] = entry | |
300 | if entry.dm_nonnormal: |
|
|||
301 | self.nonnormalset.add(filename) |
|
|||
302 | new = True |
|
282 | new = True | |
303 | elif not entry.tracked: |
|
283 | elif not entry.tracked: | |
304 | self._dirs_incr(filename, entry) |
|
284 | self._dirs_incr(filename, entry) | |
@@ -321,29 +301,11 b' class dirstatemap(object):' | |||||
321 | if not entry.merged: |
|
301 | if not entry.merged: | |
322 | self.copymap.pop(f, None) |
|
302 | self.copymap.pop(f, None) | |
323 | if entry.added: |
|
303 | if entry.added: | |
324 | self.nonnormalset.discard(f) |
|
|||
325 | self._map.pop(f, None) |
|
304 | self._map.pop(f, None) | |
326 | else: |
|
305 | else: | |
327 | self.nonnormalset.add(f) |
|
|||
328 | if entry.from_p2: |
|
|||
329 | self.otherparentset.add(f) |
|
|||
330 | entry.set_untracked() |
|
306 | entry.set_untracked() | |
331 | return True |
|
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 | @propertycache |
|
309 | @propertycache | |
348 | def filefoldmap(self): |
|
310 | def filefoldmap(self): | |
349 | """Returns a dictionary mapping normalized case paths to their |
|
311 | """Returns a dictionary mapping normalized case paths to their | |
@@ -433,13 +395,7 b' class dirstatemap(object):' | |||||
433 | self._dirtyparents = True |
|
395 | self._dirtyparents = True | |
434 | copies = {} |
|
396 | copies = {} | |
435 | if fold_p2: |
|
397 | if fold_p2: | |
436 | candidatefiles = self.non_normal_or_other_parent_paths() |
|
398 | for f, s in pycompat.iteritems(self._map): | |
437 |
|
||||
438 | for f in candidatefiles: |
|
|||
439 | s = self.get(f) |
|
|||
440 | if s is None: |
|
|||
441 | continue |
|
|||
442 |
|
||||
443 | # Discard "merged" markers when moving away from a merge state |
|
399 | # Discard "merged" markers when moving away from a merge state | |
444 | if s.merged or s.from_p2: |
|
400 | if s.merged or s.from_p2: | |
445 | source = self.copymap.pop(f, None) |
|
401 | source = self.copymap.pop(f, None) | |
@@ -504,22 +460,6 b' class dirstatemap(object):' | |||||
504 | ) |
|
460 | ) | |
505 | st.close() |
|
461 | st.close() | |
506 | self._dirtyparents = False |
|
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 | @propertycache |
|
464 | @propertycache | |
525 | def identity(self): |
|
465 | def identity(self): | |
@@ -643,7 +583,6 b' if rustmod is not None:' | |||||
643 | elif (p1_tracked or p2_tracked) and not wc_tracked: |
|
583 | elif (p1_tracked or p2_tracked) and not wc_tracked: | |
644 | # XXX might be merged and removed ? |
|
584 | # XXX might be merged and removed ? | |
645 | self[filename] = DirstateItem.from_v1_data(b'r', 0, 0, 0) |
|
585 | self[filename] = DirstateItem.from_v1_data(b'r', 0, 0, 0) | |
646 | self.nonnormalset.add(filename) |
|
|||
647 | elif clean_p2 and wc_tracked: |
|
586 | elif clean_p2 and wc_tracked: | |
648 | if p1_tracked or self.get(filename) is not None: |
|
587 | if p1_tracked or self.get(filename) is not None: | |
649 | # XXX the `self.get` call is catching some case in |
|
588 | # XXX the `self.get` call is catching some case in | |
@@ -670,7 +609,6 b' if rustmod is not None:' | |||||
670 | raise error.ProgrammingError(msg) |
|
609 | raise error.ProgrammingError(msg) | |
671 | mode, size, mtime = parentfiledata |
|
610 | mode, size, mtime = parentfiledata | |
672 | self.addfile(filename, mode=mode, size=size, mtime=mtime) |
|
611 | self.addfile(filename, mode=mode, size=size, mtime=mtime) | |
673 | self.nonnormalset.discard(filename) |
|
|||
674 | else: |
|
612 | else: | |
675 | assert False, 'unreachable' |
|
613 | assert False, 'unreachable' | |
676 |
|
614 | |||
@@ -710,9 +648,6 b' if rustmod is not None:' | |||||
710 | def removefile(self, *args, **kwargs): |
|
648 | def removefile(self, *args, **kwargs): | |
711 | return self._rustmap.removefile(*args, **kwargs) |
|
649 | return self._rustmap.removefile(*args, **kwargs) | |
712 |
|
650 | |||
713 | def nonnormalentries(self): |
|
|||
714 | return self._rustmap.nonnormalentries() |
|
|||
715 |
|
||||
716 | def get(self, *args, **kwargs): |
|
651 | def get(self, *args, **kwargs): | |
717 | return self._rustmap.get(*args, **kwargs) |
|
652 | return self._rustmap.get(*args, **kwargs) | |
718 |
|
653 | |||
@@ -790,13 +725,17 b' if rustmod is not None:' | |||||
790 | self._dirtyparents = True |
|
725 | self._dirtyparents = True | |
791 | copies = {} |
|
726 | copies = {} | |
792 | if fold_p2: |
|
727 | if fold_p2: | |
793 | candidatefiles = self.non_normal_or_other_parent_paths() |
|
728 | # Collect into an intermediate list to avoid a `RuntimeError` | |
794 |
|
729 | # exception due to mutation during iteration. | ||
795 | for f in candidatefiles: |
|
730 | # TODO: move this the whole loop to Rust where `iter_mut` | |
796 | s = self.get(f) |
|
731 | # enables in-place mutation of elements of a collection while | |
797 | if s is None: |
|
732 | # iterating it, without mutating the collection itself. | |
798 |
|
|
733 | candidatefiles = [ | |
799 |
|
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 | # Discard "merged" markers when moving away from a merge state |
|
739 | # Discard "merged" markers when moving away from a merge state | |
801 | if s.merged: |
|
740 | if s.merged: | |
802 | source = self.copymap.get(f) |
|
741 | source = self.copymap.get(f) | |
@@ -965,19 +904,6 b' if rustmod is not None:' | |||||
965 | self._rustmap |
|
904 | self._rustmap | |
966 | return self.identity |
|
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 | @propertycache |
|
907 | @propertycache | |
982 | def dirfoldmap(self): |
|
908 | def dirfoldmap(self): | |
983 | f = {} |
|
909 | f = {} |
@@ -361,22 +361,6 b' class DirstateItem(object):' | |||||
361 | """ |
|
361 | """ | |
362 | return self.removed and self._merged |
|
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 | def v1_state(self): |
|
364 | def v1_state(self): | |
381 | """return a "state" suitable for v1 serialization""" |
|
365 | """return a "state" suitable for v1 serialization""" | |
382 | if not (self._p1_tracked or self._p2_tracked or self._wc_tracked): |
|
366 | if not (self._p1_tracked or self._p2_tracked or self._wc_tracked): |
@@ -6,6 +6,7 b'' | |||||
6 | // GNU General Public License version 2 or any later version. |
|
6 | // GNU General Public License version 2 or any later version. | |
7 |
|
7 | |||
8 | use crate::dirstate::parsers::Timestamp; |
|
8 | use crate::dirstate::parsers::Timestamp; | |
|
9 | use crate::errors::HgError; | |||
9 | use crate::{ |
|
10 | use crate::{ | |
10 | dirstate::EntryState, |
|
11 | dirstate::EntryState, | |
11 | dirstate::SIZE_FROM_OTHER_PARENT, |
|
12 | dirstate::SIZE_FROM_OTHER_PARENT, | |
@@ -16,7 +17,6 b' use crate::{' | |||||
16 | StateMap, |
|
17 | StateMap, | |
17 | }; |
|
18 | }; | |
18 | use micro_timer::timed; |
|
19 | use micro_timer::timed; | |
19 | use std::collections::HashSet; |
|
|||
20 | use std::iter::FromIterator; |
|
20 | use std::iter::FromIterator; | |
21 | use std::ops::Deref; |
|
21 | use std::ops::Deref; | |
22 |
|
22 | |||
@@ -26,8 +26,6 b' pub struct DirstateMap {' | |||||
26 | pub copy_map: CopyMap, |
|
26 | pub copy_map: CopyMap, | |
27 | pub dirs: Option<DirsMultiset>, |
|
27 | pub dirs: Option<DirsMultiset>, | |
28 | pub all_dirs: Option<DirsMultiset>, |
|
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 | /// Should only really be used in python interface code, for clarity |
|
31 | /// Should only really be used in python interface code, for clarity | |
@@ -58,8 +56,6 b' impl DirstateMap {' | |||||
58 | pub fn clear(&mut self) { |
|
56 | pub fn clear(&mut self) { | |
59 | self.state_map = StateMap::default(); |
|
57 | self.state_map = StateMap::default(); | |
60 | self.copy_map.clear(); |
|
58 | self.copy_map.clear(); | |
61 | self.non_normal_set = None; |
|
|||
62 | self.other_parent_set = None; |
|
|||
63 | } |
|
59 | } | |
64 |
|
60 | |||
65 | pub fn set_entry(&mut self, filename: &HgPath, entry: DirstateEntry) { |
|
61 | pub fn set_entry(&mut self, filename: &HgPath, entry: DirstateEntry) { | |
@@ -84,18 +80,6 b' impl DirstateMap {' | |||||
84 | } |
|
80 | } | |
85 | } |
|
81 | } | |
86 | self.state_map.insert(filename.to_owned(), entry.to_owned()); |
|
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 | Ok(()) |
|
83 | Ok(()) | |
100 | } |
|
84 | } | |
101 |
|
85 | |||
@@ -126,9 +110,6 b' impl DirstateMap {' | |||||
126 | { |
|
110 | { | |
127 | // other parent |
|
111 | // other parent | |
128 | size = SIZE_FROM_OTHER_PARENT; |
|
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 | self.state_map |
|
130 | self.state_map | |
150 | .insert(filename.to_owned(), DirstateEntry::new_removed(size)); |
|
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 | Ok(()) |
|
132 | Ok(()) | |
155 | } |
|
133 | } | |
156 |
|
134 | |||
@@ -173,92 +151,11 b' impl DirstateMap {' | |||||
173 | all_dirs.delete_path(filename)?; |
|
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 | self.copy_map.remove(filename); |
|
154 | self.copy_map.remove(filename); | |
181 |
|
155 | |||
182 | Ok(()) |
|
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 | /// Both of these setters and their uses appear to be the simplest way to |
|
159 | /// Both of these setters and their uses appear to be the simplest way to | |
263 | /// emulate a Python lazy property, but it is ugly and unidiomatic. |
|
160 | /// emulate a Python lazy property, but it is ugly and unidiomatic. | |
264 | /// TODO One day, rewriting this struct using the typestate might be a |
|
161 | /// TODO One day, rewriting this struct using the typestate might be a | |
@@ -326,12 +223,8 b' impl DirstateMap {' | |||||
326 | &mut self, |
|
223 | &mut self, | |
327 | parents: DirstateParents, |
|
224 | parents: DirstateParents, | |
328 | now: Timestamp, |
|
225 | now: Timestamp, | |
329 |
) -> Result<Vec<u8>, |
|
226 | ) -> Result<Vec<u8>, HgError> { | |
330 | let packed = |
|
227 | pack_dirstate(&mut self.state_map, &self.copy_map, parents, now) | |
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) |
|
|||
335 | } |
|
228 | } | |
336 | } |
|
229 | } | |
337 |
|
230 | |||
@@ -366,49 +259,5 b' mod tests {' | |||||
366 | .unwrap(); |
|
259 | .unwrap(); | |
367 |
|
260 | |||
368 | assert_eq!(1, map.len()); |
|
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 | (self.state().into(), self.mode(), self.size(), self.mtime()) |
|
294 | (self.state().into(), self.mode(), self.size(), self.mtime()) | |
295 | } |
|
295 | } | |
296 |
|
296 | |||
297 |
pub fn is_ |
|
297 | pub(crate) fn is_from_other_parent(&self) -> bool { | |
298 | self.state() != EntryState::Normal || self.mtime() == MTIME_UNSET |
|
|||
299 | } |
|
|||
300 |
|
||||
301 | pub fn is_from_other_parent(&self) -> bool { |
|
|||
302 | self.state() == EntryState::Normal |
|
298 | self.state() == EntryState::Normal | |
303 | && self.size() == SIZE_FROM_OTHER_PARENT |
|
299 | && self.size() == SIZE_FROM_OTHER_PARENT | |
304 | } |
|
300 | } |
@@ -701,27 +701,6 b" impl<'on_disk> DirstateMap<'on_disk> {" | |||||
701 | Ok(()) |
|
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 | fn count_dropped_path(unreachable_bytes: &mut u32, path: &Cow<HgPath>) { |
|
704 | fn count_dropped_path(unreachable_bytes: &mut u32, path: &Cow<HgPath>) { | |
726 | if let Cow::Borrowed(path) = path { |
|
705 | if let Cow::Borrowed(path) = path { | |
727 | *unreachable_bytes += path.len() as u32 |
|
706 | *unreachable_bytes += path.len() as u32 | |
@@ -917,69 +896,6 b" impl<'on_disk> super::dispatch::Dirstate" | |||||
917 | Ok(()) |
|
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 | fn has_tracked_dir( |
|
899 | fn has_tracked_dir( | |
984 | &mut self, |
|
900 | &mut self, | |
985 | directory: &HgPath, |
|
901 | directory: &HgPath, |
@@ -67,82 +67,6 b' pub trait DirstateMapMethods {' | |||||
67 | filename: &HgPath, |
|
67 | filename: &HgPath, | |
68 | ) -> Result<(), DirstateError>; |
|
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 | /// Returns whether the sub-tree rooted at the given directory contains any |
|
70 | /// Returns whether the sub-tree rooted at the given directory contains any | |
147 | /// tracked file. |
|
71 | /// tracked file. | |
148 | /// |
|
72 | /// | |
@@ -330,66 +254,6 b' impl DirstateMapMethods for DirstateMap ' | |||||
330 | self.drop_entry_and_copy_source(filename) |
|
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 | fn has_tracked_dir( |
|
257 | fn has_tracked_dir( | |
394 | &mut self, |
|
258 | &mut self, | |
395 | directory: &HgPath, |
|
259 | directory: &HgPath, | |
@@ -406,7 +270,7 b' impl DirstateMapMethods for DirstateMap ' | |||||
406 | parents: DirstateParents, |
|
270 | parents: DirstateParents, | |
407 | now: Timestamp, |
|
271 | now: Timestamp, | |
408 | ) -> Result<Vec<u8>, DirstateError> { |
|
272 | ) -> Result<Vec<u8>, DirstateError> { | |
409 | self.pack(parents, now) |
|
273 | Ok(self.pack(parents, now)?) | |
410 | } |
|
274 | } | |
411 |
|
275 | |||
412 | fn pack_v2( |
|
276 | fn pack_v2( |
@@ -51,56 +51,6 b' impl DirstateMapMethods for OwningDirsta' | |||||
51 | self.get_mut().drop_entry_and_copy_source(filename) |
|
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 | fn has_tracked_dir( |
|
54 | fn has_tracked_dir( | |
105 | &mut self, |
|
55 | &mut self, | |
106 | directory: &HgPath, |
|
56 | directory: &HgPath, |
@@ -13,7 +13,6 b' mod copymap;' | |||||
13 | mod dirs_multiset; |
|
13 | mod dirs_multiset; | |
14 | mod dirstate_map; |
|
14 | mod dirstate_map; | |
15 | mod item; |
|
15 | mod item; | |
16 | mod non_normal_entries; |
|
|||
17 | mod status; |
|
16 | mod status; | |
18 | use self::item::DirstateItem; |
|
17 | use self::item::DirstateItem; | |
19 | use crate::{ |
|
18 | use crate::{ |
@@ -13,16 +13,12 b' use std::convert::TryInto;' | |||||
13 |
|
13 | |||
14 | use cpython::{ |
|
14 | use cpython::{ | |
15 | exc, PyBool, PyBytes, PyClone, PyDict, PyErr, PyList, PyNone, PyObject, |
|
15 | exc, PyBool, PyBytes, PyClone, PyDict, PyErr, PyList, PyNone, PyObject, | |
16 |
PyResult |
|
16 | PyResult, Python, PythonObject, ToPyObject, UnsafePyLeaked, | |
17 | UnsafePyLeaked, |
|
|||
18 | }; |
|
17 | }; | |
19 |
|
18 | |||
20 | use crate::{ |
|
19 | use crate::{ | |
21 | dirstate::copymap::{CopyMap, CopyMapItemsIterator, CopyMapKeysIterator}, |
|
20 | dirstate::copymap::{CopyMap, CopyMapItemsIterator, CopyMapKeysIterator}, | |
22 | dirstate::item::DirstateItem, |
|
21 | dirstate::item::DirstateItem, | |
23 | dirstate::non_normal_entries::{ |
|
|||
24 | NonNormalEntries, NonNormalEntriesIterator, |
|
|||
25 | }, |
|
|||
26 | pybytes_deref::PyBytesDeref, |
|
22 | pybytes_deref::PyBytesDeref, | |
27 | }; |
|
23 | }; | |
28 | use hg::{ |
|
24 | use hg::{ | |
@@ -185,100 +181,6 b' py_class!(pub class DirstateMap |py| {' | |||||
185 | Ok(PyNone) |
|
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 | def hastrackeddir(&self, d: PyObject) -> PyResult<PyBool> { |
|
184 | def hastrackeddir(&self, d: PyObject) -> PyResult<PyBool> { | |
283 | let d = d.extract::<PyBytes>(py)?; |
|
185 | let d = d.extract::<PyBytes>(py)?; | |
284 | Ok(self.inner(py).borrow_mut() |
|
186 | Ok(self.inner(py).borrow_mut() |
@@ -95,16 +95,6 b' py_class!(pub class DirstateItem |py| {' | |||||
95 | Ok(self.entry(py).get().from_p2_removed()) |
|
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 | def v1_state(&self) -> PyResult<PyBytes> { |
|
98 | def v1_state(&self) -> PyResult<PyBytes> { | |
109 | let (state, _mode, _size, _mtime) = self.entry(py).get().v1_data(); |
|
99 | let (state, _mode, _size, _mtime) = self.entry(py).get().v1_data(); | |
110 | let state_byte: u8 = state.into(); |
|
100 | let state_byte: u8 = state.into(); |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now