Show More
@@ -264,7 +264,7 b' PyObject *make_file_foldmap(PyObject *se' | |||
|
264 | 264 | } |
|
265 | 265 | |
|
266 | 266 | tuple = (dirstateItemObject *)v; |
|
267 | if (tuple->state != 'r') { | |
|
267 | if (tuple->flags | dirstate_flag_wc_tracked) { | |
|
268 | 268 | PyObject *normed; |
|
269 | 269 | if (table != NULL) { |
|
270 | 270 | normed = _asciitransform(k, table, |
@@ -177,7 +177,8 b' static int dirs_fromdict(PyObject *dirs,' | |||
|
177 | 177 | "expected a dirstate tuple"); |
|
178 | 178 | return -1; |
|
179 | 179 | } |
|
180 |
if (((dirstateItemObject *)value)-> |
|
|
180 | if (!(((dirstateItemObject *)value)->flags & | |
|
181 | dirstate_flag_wc_tracked)) | |
|
181 | 182 | continue; |
|
182 | 183 | } |
|
183 | 184 |
@@ -89,60 +89,45 b' static PyObject *dirstate_item_new(PyTyp' | |||
|
89 | 89 | if (!t) { |
|
90 | 90 | return NULL; |
|
91 | 91 | } |
|
92 | t->state = 'r'; | |
|
92 | ||
|
93 | t->flags = 0; | |
|
94 | if (wc_tracked) { | |
|
95 | t->flags |= dirstate_flag_wc_tracked; | |
|
96 | } | |
|
97 | if (p1_tracked) { | |
|
98 | t->flags |= dirstate_flag_p1_tracked; | |
|
99 | } | |
|
100 | if (p2_tracked) { | |
|
101 | t->flags |= dirstate_flag_p2_tracked; | |
|
102 | } | |
|
103 | if (possibly_dirty) { | |
|
104 | t->flags |= dirstate_flag_possibly_dirty; | |
|
105 | } | |
|
106 | if (merged) { | |
|
107 | t->flags |= dirstate_flag_merged; | |
|
108 | } | |
|
109 | if (clean_p1) { | |
|
110 | t->flags |= dirstate_flag_clean_p1; | |
|
111 | } | |
|
112 | if (clean_p2) { | |
|
113 | t->flags |= dirstate_flag_clean_p2; | |
|
114 | } | |
|
93 | 115 | t->mode = 0; |
|
94 | 116 | t->size = dirstate_v1_nonnormal; |
|
95 | 117 | t->mtime = ambiguous_time; |
|
96 | if (!(p1_tracked || p2_tracked || wc_tracked)) { | |
|
97 | /* Nothing special to do, file is untracked */ | |
|
98 | } else if (merged) { | |
|
99 | t->state = 'm'; | |
|
100 | t->size = dirstate_v1_from_p2; | |
|
101 | t->mtime = ambiguous_time; | |
|
102 | } else if (!(p1_tracked || p2_tracked) && wc_tracked) { | |
|
103 | t->state = 'a'; | |
|
104 | t->size = dirstate_v1_nonnormal; | |
|
105 | t->mtime = ambiguous_time; | |
|
106 | } else if ((p1_tracked || p2_tracked) && !wc_tracked) { | |
|
107 | t->state = 'r'; | |
|
108 | t->size = 0; | |
|
109 | t->mtime = 0; | |
|
110 | } else if (clean_p2 && wc_tracked) { | |
|
111 | t->state = 'n'; | |
|
112 | t->size = dirstate_v1_from_p2; | |
|
113 | t->mtime = ambiguous_time; | |
|
114 | } else if (!p1_tracked && p2_tracked && wc_tracked) { | |
|
115 | t->state = 'n'; | |
|
116 | t->size = dirstate_v1_from_p2; | |
|
117 | t->mtime = ambiguous_time; | |
|
118 | } else if (possibly_dirty) { | |
|
119 | t->state = 'n'; | |
|
120 | t->size = dirstate_v1_nonnormal; | |
|
121 | t->mtime = ambiguous_time; | |
|
122 | } else if (wc_tracked) { | |
|
123 | /* this is a "normal" file */ | |
|
124 | if (parentfiledata == Py_None) { | |
|
125 | PyErr_SetString( | |
|
126 | PyExc_RuntimeError, | |
|
127 | "failed to pass parentfiledata for a normal file"); | |
|
128 | return NULL; | |
|
129 | } | |
|
118 | if (parentfiledata != Py_None) { | |
|
130 | 119 | if (!PyTuple_CheckExact(parentfiledata)) { |
|
131 | 120 | PyErr_SetString( |
|
132 | 121 | PyExc_TypeError, |
|
133 | 122 | "parentfiledata should be a Tuple or None"); |
|
134 | 123 | return NULL; |
|
135 | 124 | } |
|
136 | t->state = 'n'; | |
|
137 | 125 | t->mode = |
|
138 | 126 | (int)PyLong_AsLong(PyTuple_GetItem(parentfiledata, 0)); |
|
139 | 127 | t->size = |
|
140 | 128 | (int)PyLong_AsLong(PyTuple_GetItem(parentfiledata, 1)); |
|
141 | 129 | t->mtime = |
|
142 | 130 | (int)PyLong_AsLong(PyTuple_GetItem(parentfiledata, 2)); |
|
143 | } else { | |
|
144 | PyErr_SetString(PyExc_RuntimeError, "unreachable"); | |
|
145 | return NULL; | |
|
146 | 131 | } |
|
147 | 132 | return (PyObject *)t; |
|
148 | 133 | } |
@@ -154,42 +139,69 b' static void dirstate_item_dealloc(PyObje' | |||
|
154 | 139 | |
|
155 | 140 | static inline bool dirstate_item_c_tracked(dirstateItemObject *self) |
|
156 | 141 | { |
|
157 | return (self->state == 'a' || self->state == 'm' || self->state == 'n'); | |
|
142 | return (self->flags & dirstate_flag_wc_tracked); | |
|
158 | 143 | } |
|
159 | 144 | |
|
160 | 145 | static inline bool dirstate_item_c_added(dirstateItemObject *self) |
|
161 | 146 | { |
|
162 | return (self->state == 'a'); | |
|
147 | char mask = (dirstate_flag_wc_tracked | dirstate_flag_p1_tracked | | |
|
148 | dirstate_flag_p2_tracked); | |
|
149 | char target = dirstate_flag_wc_tracked; | |
|
150 | return (self->flags & mask) == target; | |
|
163 | 151 | } |
|
164 | 152 | |
|
165 | 153 | static inline bool dirstate_item_c_removed(dirstateItemObject *self) |
|
166 | 154 | { |
|
167 | return (self->state == 'r'); | |
|
155 | if (self->flags & dirstate_flag_wc_tracked) { | |
|
156 | return false; | |
|
157 | } | |
|
158 | return (self->flags & | |
|
159 | (dirstate_flag_p1_tracked | dirstate_flag_p2_tracked)); | |
|
168 | 160 | } |
|
169 | 161 | |
|
170 | 162 | static inline bool dirstate_item_c_merged(dirstateItemObject *self) |
|
171 | 163 | { |
|
172 | return (self->state == 'm'); | |
|
164 | return ((self->flags & dirstate_flag_wc_tracked) && | |
|
165 | (self->flags & dirstate_flag_merged)); | |
|
173 | 166 | } |
|
174 | 167 | |
|
175 | 168 | static inline bool dirstate_item_c_merged_removed(dirstateItemObject *self) |
|
176 | 169 | { |
|
177 | return (self->state == 'r' && self->size == dirstate_v1_nonnormal); | |
|
170 | if (!dirstate_item_c_removed(self)) { | |
|
171 | return false; | |
|
172 | } | |
|
173 | return (self->flags & dirstate_flag_merged); | |
|
178 | 174 | } |
|
179 | 175 | |
|
180 | 176 | static inline bool dirstate_item_c_from_p2(dirstateItemObject *self) |
|
181 | 177 | { |
|
182 | return (self->state == 'n' && self->size == dirstate_v1_from_p2); | |
|
178 | if (!dirstate_item_c_tracked(self)) { | |
|
179 | return false; | |
|
180 | } | |
|
181 | return (self->flags & dirstate_flag_clean_p2); | |
|
183 | 182 | } |
|
184 | 183 | |
|
185 | 184 | static inline bool dirstate_item_c_from_p2_removed(dirstateItemObject *self) |
|
186 | 185 | { |
|
187 | return (self->state == 'r' && self->size == dirstate_v1_from_p2); | |
|
186 | if (!dirstate_item_c_removed(self)) { | |
|
187 | return false; | |
|
188 | } | |
|
189 | return (self->flags & dirstate_flag_clean_p2); | |
|
188 | 190 | } |
|
189 | 191 | |
|
190 | 192 | static inline char dirstate_item_c_v1_state(dirstateItemObject *self) |
|
191 | 193 | { |
|
192 | return self->state; | |
|
194 | if (self->flags & dirstate_flag_rust_special) { | |
|
195 | return ' '; | |
|
196 | } else if (dirstate_item_c_removed(self)) { | |
|
197 | return 'r'; | |
|
198 | } else if (dirstate_item_c_merged(self)) { | |
|
199 | return 'm'; | |
|
200 | } else if (dirstate_item_c_added(self)) { | |
|
201 | return 'a'; | |
|
202 | } else { | |
|
203 | return 'n'; | |
|
204 | } | |
|
193 | 205 | } |
|
194 | 206 | |
|
195 | 207 | static inline int dirstate_item_c_v1_mode(dirstateItemObject *self) |
@@ -199,12 +211,44 b' static inline int dirstate_item_c_v1_mod' | |||
|
199 | 211 | |
|
200 | 212 | static inline int dirstate_item_c_v1_size(dirstateItemObject *self) |
|
201 | 213 | { |
|
214 | if (self->flags & dirstate_flag_rust_special) { | |
|
202 | 215 | return self->size; |
|
216 | } else if (dirstate_item_c_merged_removed(self)) { | |
|
217 | return dirstate_v1_nonnormal; | |
|
218 | } else if (dirstate_item_c_from_p2_removed(self)) { | |
|
219 | return dirstate_v1_from_p2; | |
|
220 | } else if (dirstate_item_c_removed(self)) { | |
|
221 | return 0; | |
|
222 | } else if (dirstate_item_c_merged(self)) { | |
|
223 | return dirstate_v1_from_p2; | |
|
224 | } else if (dirstate_item_c_added(self)) { | |
|
225 | return dirstate_v1_nonnormal; | |
|
226 | } else if (dirstate_item_c_from_p2(self)) { | |
|
227 | return dirstate_v1_from_p2; | |
|
228 | } else if (self->flags & dirstate_flag_possibly_dirty) { | |
|
229 | return self->size; /* NON NORMAL ? */ | |
|
230 | } else { | |
|
231 | return self->size; | |
|
232 | } | |
|
203 | 233 | } |
|
204 | 234 | |
|
205 | 235 | static inline int dirstate_item_c_v1_mtime(dirstateItemObject *self) |
|
206 | 236 | { |
|
237 | if (self->flags & dirstate_flag_rust_special) { | |
|
207 | 238 | return self->mtime; |
|
239 | } else if (dirstate_item_c_removed(self)) { | |
|
240 | return 0; | |
|
241 | } else if (self->flags & dirstate_flag_possibly_dirty) { | |
|
242 | return ambiguous_time; | |
|
243 | } else if (dirstate_item_c_merged(self)) { | |
|
244 | return ambiguous_time; | |
|
245 | } else if (dirstate_item_c_added(self)) { | |
|
246 | return ambiguous_time; | |
|
247 | } else if (dirstate_item_c_from_p2(self)) { | |
|
248 | return ambiguous_time; | |
|
249 | } else { | |
|
250 | return self->mtime; | |
|
251 | } | |
|
208 | 252 | } |
|
209 | 253 | |
|
210 | 254 | static PyObject *dirstate_item_v1_state(dirstateItemObject *self) |
@@ -253,10 +297,76 b' dirstate_item_from_v1_data(char state, i' | |||
|
253 | 297 | if (!t) { |
|
254 | 298 | return NULL; |
|
255 | 299 | } |
|
256 | t->state = state; | |
|
300 | ||
|
301 | if (state == 'm') { | |
|
302 | t->flags = | |
|
303 | (dirstate_flag_wc_tracked | dirstate_flag_p1_tracked | | |
|
304 | dirstate_flag_p2_tracked | dirstate_flag_merged); | |
|
305 | t->mode = 0; | |
|
306 | t->size = dirstate_v1_from_p2; | |
|
307 | t->mtime = ambiguous_time; | |
|
308 | } else if (state == 'a') { | |
|
309 | t->flags = dirstate_flag_wc_tracked; | |
|
310 | t->mode = 0; | |
|
311 | t->size = dirstate_v1_nonnormal; | |
|
312 | t->mtime = ambiguous_time; | |
|
313 | } else if (state == 'r') { | |
|
314 | t->mode = 0; | |
|
315 | t->size = 0; | |
|
316 | t->mtime = 0; | |
|
317 | if (size == dirstate_v1_nonnormal) { | |
|
318 | t->flags = | |
|
319 | (dirstate_flag_p1_tracked | | |
|
320 | dirstate_flag_p2_tracked | dirstate_flag_merged); | |
|
321 | } else if (size == dirstate_v1_from_p2) { | |
|
322 | t->flags = | |
|
323 | (dirstate_flag_p2_tracked | dirstate_flag_clean_p2); | |
|
324 | } else { | |
|
325 | t->flags = dirstate_flag_p1_tracked; | |
|
326 | } | |
|
327 | } else if (state == 'n') { | |
|
328 | if (size == dirstate_v1_from_p2) { | |
|
329 | t->flags = | |
|
330 | (dirstate_flag_wc_tracked | | |
|
331 | dirstate_flag_p2_tracked | dirstate_flag_clean_p2); | |
|
332 | t->mode = 0; | |
|
333 | t->size = dirstate_v1_from_p2; | |
|
334 | t->mtime = ambiguous_time; | |
|
335 | } else if (size == dirstate_v1_nonnormal) { | |
|
336 | t->flags = (dirstate_flag_wc_tracked | | |
|
337 | dirstate_flag_p1_tracked | | |
|
338 | dirstate_flag_possibly_dirty); | |
|
339 | t->mode = 0; | |
|
340 | t->size = dirstate_v1_nonnormal; | |
|
341 | t->mtime = ambiguous_time; | |
|
342 | } else if (mtime == ambiguous_time) { | |
|
343 | t->flags = (dirstate_flag_wc_tracked | | |
|
344 | dirstate_flag_p1_tracked | | |
|
345 | dirstate_flag_possibly_dirty); | |
|
346 | t->mode = mode; | |
|
347 | t->size = size; | |
|
348 | t->mtime = 0; | |
|
349 | } else { | |
|
350 | t->flags = (dirstate_flag_wc_tracked | | |
|
351 | dirstate_flag_p1_tracked); | |
|
257 | 352 | t->mode = mode; |
|
258 | 353 | t->size = size; |
|
259 | 354 | t->mtime = mtime; |
|
355 | } | |
|
356 | } else if (state == ' ') { | |
|
357 | /* XXX Rust is using this special case, it should be clean up | |
|
358 | * later. */ | |
|
359 | t->flags = dirstate_flag_rust_special; | |
|
360 | t->mode = mode; | |
|
361 | t->size = size; | |
|
362 | t->mtime = mtime; | |
|
363 | } else { | |
|
364 | PyErr_Format(PyExc_RuntimeError, | |
|
365 | "unknown state: `%c` (%d, %d, %d)", state, mode, | |
|
366 | size, mtime, NULL); | |
|
367 | return NULL; | |
|
368 | } | |
|
369 | ||
|
260 | 370 | return t; |
|
261 | 371 | } |
|
262 | 372 | |
@@ -284,7 +394,7 b' static PyObject *dirstate_item_new_added' | |||
|
284 | 394 | if (!t) { |
|
285 | 395 | return NULL; |
|
286 | 396 | } |
|
287 | t->state = 'a'; | |
|
397 | t->flags = dirstate_flag_wc_tracked; | |
|
288 | 398 | t->mode = 0; |
|
289 | 399 | t->size = dirstate_v1_nonnormal; |
|
290 | 400 | t->mtime = ambiguous_time; |
@@ -301,7 +411,8 b' static PyObject *dirstate_item_new_merge' | |||
|
301 | 411 | if (!t) { |
|
302 | 412 | return NULL; |
|
303 | 413 | } |
|
304 | t->state = 'm'; | |
|
414 | t->flags = (dirstate_flag_wc_tracked | dirstate_flag_p1_tracked | | |
|
415 | dirstate_flag_p2_tracked | dirstate_flag_merged); | |
|
305 | 416 | t->mode = 0; |
|
306 | 417 | t->size = dirstate_v1_from_p2; |
|
307 | 418 | t->mtime = ambiguous_time; |
@@ -320,7 +431,8 b' static PyObject *dirstate_item_new_from_' | |||
|
320 | 431 | if (!t) { |
|
321 | 432 | return NULL; |
|
322 | 433 | } |
|
323 | t->state = 'n'; | |
|
434 | t->flags = (dirstate_flag_wc_tracked | dirstate_flag_p2_tracked | | |
|
435 | dirstate_flag_clean_p2); | |
|
324 | 436 | t->mode = 0; |
|
325 | 437 | t->size = dirstate_v1_from_p2; |
|
326 | 438 | t->mtime = ambiguous_time; |
@@ -339,7 +451,8 b' static PyObject *dirstate_item_new_possi' | |||
|
339 | 451 | if (!t) { |
|
340 | 452 | return NULL; |
|
341 | 453 | } |
|
342 | t->state = 'n'; | |
|
454 | t->flags = (dirstate_flag_wc_tracked | dirstate_flag_p1_tracked | | |
|
455 | dirstate_flag_possibly_dirty); | |
|
343 | 456 | t->mode = 0; |
|
344 | 457 | t->size = dirstate_v1_nonnormal; |
|
345 | 458 | t->mtime = ambiguous_time; |
@@ -363,7 +476,7 b' static PyObject *dirstate_item_new_norma' | |||
|
363 | 476 | if (!t) { |
|
364 | 477 | return NULL; |
|
365 | 478 | } |
|
366 | t->state = 'n'; | |
|
479 | t->flags = (dirstate_flag_wc_tracked | dirstate_flag_p1_tracked); | |
|
367 | 480 | t->mode = mode; |
|
368 | 481 | t->size = size; |
|
369 | 482 | t->mtime = mtime; |
@@ -374,22 +487,17 b' static PyObject *dirstate_item_new_norma' | |||
|
374 | 487 | to make sure it is correct. */ |
|
375 | 488 | static PyObject *dirstate_item_set_possibly_dirty(dirstateItemObject *self) |
|
376 | 489 | { |
|
377 | self->mtime = ambiguous_time; | |
|
490 | if (self->flags |= dirstate_flag_possibly_dirty) { | |
|
378 | 491 | Py_RETURN_NONE; |
|
379 | 492 | } |
|
493 | } | |
|
380 | 494 | |
|
381 | 495 | static PyObject *dirstate_item_set_untracked(dirstateItemObject *self) |
|
382 | 496 | { |
|
383 | if (self->state == 'm') { | |
|
384 | self->size = dirstate_v1_nonnormal; | |
|
385 | } else if (self->state == 'n' && self->size == dirstate_v1_from_p2) { | |
|
386 | self->size = dirstate_v1_from_p2; | |
|
387 | } else { | |
|
388 | self->size = 0; | |
|
389 | } | |
|
390 | self->state = 'r'; | |
|
497 | self->flags &= ~dirstate_flag_wc_tracked; | |
|
391 | 498 | self->mode = 0; |
|
392 | 499 | self->mtime = 0; |
|
500 | self->size = 0; | |
|
393 | 501 | Py_RETURN_NONE; |
|
394 | 502 | } |
|
395 | 503 | |
@@ -713,19 +821,21 b' static PyObject *nonnormalotherparentent' | |||
|
713 | 821 | } |
|
714 | 822 | t = (dirstateItemObject *)v; |
|
715 | 823 | |
|
716 | if (t->state == 'n' && t->size == -2) { | |
|
824 | if (dirstate_item_c_from_p2(t)) { | |
|
717 | 825 | if (PySet_Add(otherpset, fname) == -1) { |
|
718 | 826 | goto bail; |
|
719 | 827 | } |
|
720 | 828 | } |
|
721 | ||
|
722 | if (t->state == 'n' && t->mtime != -1) { | |
|
723 | continue; | |
|
724 | } | |
|
829 | if (!(t->flags & dirstate_flag_wc_tracked) || | |
|
830 | !(t->flags & | |
|
831 | (dirstate_flag_p1_tracked | dirstate_flag_p2_tracked)) || | |
|
832 | (t->flags & | |
|
833 | (dirstate_flag_possibly_dirty | dirstate_flag_merged))) { | |
|
725 | 834 | if (PySet_Add(nonnset, fname) == -1) { |
|
726 | 835 | goto bail; |
|
727 | 836 | } |
|
728 | 837 | } |
|
838 | } | |
|
729 | 839 | |
|
730 | 840 | result = Py_BuildValue("(OO)", nonnset, otherpset); |
|
731 | 841 | if (result == NULL) { |
@@ -820,10 +930,10 b' static PyObject *pack_dirstate(PyObject ' | |||
|
820 | 930 | } |
|
821 | 931 | tuple = (dirstateItemObject *)v; |
|
822 | 932 | |
|
823 | state = tuple->state; | |
|
824 | mode = tuple->mode; | |
|
825 | size = tuple->size; | |
|
826 | mtime = tuple->mtime; | |
|
933 | state = dirstate_item_c_v1_state(tuple); | |
|
934 | mode = dirstate_item_c_v1_mode(tuple); | |
|
935 | size = dirstate_item_c_v1_size(tuple); | |
|
936 | mtime = dirstate_item_c_v1_mtime(tuple); | |
|
827 | 937 | if (state == 'n' && mtime == now) { |
|
828 | 938 | /* See pure/parsers.py:pack_dirstate for why we do |
|
829 | 939 | * this. */ |
@@ -24,13 +24,22 b'' | |||
|
24 | 24 | /* clang-format off */ |
|
25 | 25 | typedef struct { |
|
26 | 26 | PyObject_HEAD |
|
27 |
char |
|
|
27 | char flags; | |
|
28 | 28 | int mode; |
|
29 | 29 | int size; |
|
30 | 30 | int mtime; |
|
31 | 31 | } dirstateItemObject; |
|
32 | 32 | /* clang-format on */ |
|
33 | 33 | |
|
34 | static const char dirstate_flag_wc_tracked = 1; | |
|
35 | static const char dirstate_flag_p1_tracked = 1 << 1; | |
|
36 | static const char dirstate_flag_p2_tracked = 1 << 2; | |
|
37 | static const char dirstate_flag_possibly_dirty = 1 << 3; | |
|
38 | static const char dirstate_flag_merged = 1 << 4; | |
|
39 | static const char dirstate_flag_clean_p1 = 1 << 5; | |
|
40 | static const char dirstate_flag_clean_p2 = 1 << 6; | |
|
41 | static const char dirstate_flag_rust_special = 1 << 7; | |
|
42 | ||
|
34 | 43 | extern PyTypeObject dirstateItemType; |
|
35 | 44 | #define dirstate_tuple_check(op) (Py_TYPE(op) == &dirstateItemType) |
|
36 | 45 |
General Comments 0
You need to be logged in to leave comments.
Login now