##// END OF EJS Templates
dirstate-item: move the C implementation to the same logic...
marmoute -
r48760:83f0e93e default
parent child Browse files
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)->state == 'r')
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 state;
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