##// END OF EJS Templates
dirstate-item: move the C implementation to the same logic...
marmoute -
r49145:83f0e93e default
parent child Browse files
Show More
@@ -264,7 +264,7 b' PyObject *make_file_foldmap(PyObject *se'
264 }
264 }
265
265
266 tuple = (dirstateItemObject *)v;
266 tuple = (dirstateItemObject *)v;
267 if (tuple->state != 'r') {
267 if (tuple->flags | dirstate_flag_wc_tracked) {
268 PyObject *normed;
268 PyObject *normed;
269 if (table != NULL) {
269 if (table != NULL) {
270 normed = _asciitransform(k, table,
270 normed = _asciitransform(k, table,
@@ -177,7 +177,8 b' static int dirs_fromdict(PyObject *dirs,'
177 "expected a dirstate tuple");
177 "expected a dirstate tuple");
178 return -1;
178 return -1;
179 }
179 }
180 if (((dirstateItemObject *)value)->state == 'r')
180 if (!(((dirstateItemObject *)value)->flags &
181 dirstate_flag_wc_tracked))
181 continue;
182 continue;
182 }
183 }
183
184
@@ -89,60 +89,45 b' static PyObject *dirstate_item_new(PyTyp'
89 if (!t) {
89 if (!t) {
90 return NULL;
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 t->mode = 0;
115 t->mode = 0;
94 t->size = dirstate_v1_nonnormal;
116 t->size = dirstate_v1_nonnormal;
95 t->mtime = ambiguous_time;
117 t->mtime = ambiguous_time;
96 if (!(p1_tracked || p2_tracked || wc_tracked)) {
118 if (parentfiledata != Py_None) {
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 }
130 if (!PyTuple_CheckExact(parentfiledata)) {
119 if (!PyTuple_CheckExact(parentfiledata)) {
131 PyErr_SetString(
120 PyErr_SetString(
132 PyExc_TypeError,
121 PyExc_TypeError,
133 "parentfiledata should be a Tuple or None");
122 "parentfiledata should be a Tuple or None");
134 return NULL;
123 return NULL;
135 }
124 }
136 t->state = 'n';
137 t->mode =
125 t->mode =
138 (int)PyLong_AsLong(PyTuple_GetItem(parentfiledata, 0));
126 (int)PyLong_AsLong(PyTuple_GetItem(parentfiledata, 0));
139 t->size =
127 t->size =
140 (int)PyLong_AsLong(PyTuple_GetItem(parentfiledata, 1));
128 (int)PyLong_AsLong(PyTuple_GetItem(parentfiledata, 1));
141 t->mtime =
129 t->mtime =
142 (int)PyLong_AsLong(PyTuple_GetItem(parentfiledata, 2));
130 (int)PyLong_AsLong(PyTuple_GetItem(parentfiledata, 2));
143 } else {
144 PyErr_SetString(PyExc_RuntimeError, "unreachable");
145 return NULL;
146 }
131 }
147 return (PyObject *)t;
132 return (PyObject *)t;
148 }
133 }
@@ -154,42 +139,69 b' static void dirstate_item_dealloc(PyObje'
154
139
155 static inline bool dirstate_item_c_tracked(dirstateItemObject *self)
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 static inline bool dirstate_item_c_added(dirstateItemObject *self)
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 static inline bool dirstate_item_c_removed(dirstateItemObject *self)
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 static inline bool dirstate_item_c_merged(dirstateItemObject *self)
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 static inline bool dirstate_item_c_merged_removed(dirstateItemObject *self)
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 static inline bool dirstate_item_c_from_p2(dirstateItemObject *self)
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 static inline bool dirstate_item_c_from_p2_removed(dirstateItemObject *self)
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 static inline char dirstate_item_c_v1_state(dirstateItemObject *self)
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 static inline int dirstate_item_c_v1_mode(dirstateItemObject *self)
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 static inline int dirstate_item_c_v1_size(dirstateItemObject *self)
212 static inline int dirstate_item_c_v1_size(dirstateItemObject *self)
201 {
213 {
202 return self->size;
214 if (self->flags & dirstate_flag_rust_special) {
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 static inline int dirstate_item_c_v1_mtime(dirstateItemObject *self)
235 static inline int dirstate_item_c_v1_mtime(dirstateItemObject *self)
206 {
236 {
207 return self->mtime;
237 if (self->flags & dirstate_flag_rust_special) {
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 static PyObject *dirstate_item_v1_state(dirstateItemObject *self)
254 static PyObject *dirstate_item_v1_state(dirstateItemObject *self)
@@ -253,10 +297,76 b' dirstate_item_from_v1_data(char state, i'
253 if (!t) {
297 if (!t) {
254 return NULL;
298 return NULL;
255 }
299 }
256 t->state = state;
300
257 t->mode = mode;
301 if (state == 'm') {
258 t->size = size;
302 t->flags =
259 t->mtime = mtime;
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);
352 t->mode = mode;
353 t->size = size;
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 return t;
370 return t;
261 }
371 }
262
372
@@ -284,7 +394,7 b' static PyObject *dirstate_item_new_added'
284 if (!t) {
394 if (!t) {
285 return NULL;
395 return NULL;
286 }
396 }
287 t->state = 'a';
397 t->flags = dirstate_flag_wc_tracked;
288 t->mode = 0;
398 t->mode = 0;
289 t->size = dirstate_v1_nonnormal;
399 t->size = dirstate_v1_nonnormal;
290 t->mtime = ambiguous_time;
400 t->mtime = ambiguous_time;
@@ -301,7 +411,8 b' static PyObject *dirstate_item_new_merge'
301 if (!t) {
411 if (!t) {
302 return NULL;
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 t->mode = 0;
416 t->mode = 0;
306 t->size = dirstate_v1_from_p2;
417 t->size = dirstate_v1_from_p2;
307 t->mtime = ambiguous_time;
418 t->mtime = ambiguous_time;
@@ -320,7 +431,8 b' static PyObject *dirstate_item_new_from_'
320 if (!t) {
431 if (!t) {
321 return NULL;
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 t->mode = 0;
436 t->mode = 0;
325 t->size = dirstate_v1_from_p2;
437 t->size = dirstate_v1_from_p2;
326 t->mtime = ambiguous_time;
438 t->mtime = ambiguous_time;
@@ -339,7 +451,8 b' static PyObject *dirstate_item_new_possi'
339 if (!t) {
451 if (!t) {
340 return NULL;
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 t->mode = 0;
456 t->mode = 0;
344 t->size = dirstate_v1_nonnormal;
457 t->size = dirstate_v1_nonnormal;
345 t->mtime = ambiguous_time;
458 t->mtime = ambiguous_time;
@@ -363,7 +476,7 b' static PyObject *dirstate_item_new_norma'
363 if (!t) {
476 if (!t) {
364 return NULL;
477 return NULL;
365 }
478 }
366 t->state = 'n';
479 t->flags = (dirstate_flag_wc_tracked | dirstate_flag_p1_tracked);
367 t->mode = mode;
480 t->mode = mode;
368 t->size = size;
481 t->size = size;
369 t->mtime = mtime;
482 t->mtime = mtime;
@@ -374,22 +487,17 b' static PyObject *dirstate_item_new_norma'
374 to make sure it is correct. */
487 to make sure it is correct. */
375 static PyObject *dirstate_item_set_possibly_dirty(dirstateItemObject *self)
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 Py_RETURN_NONE;
491 Py_RETURN_NONE;
492 }
379 }
493 }
380
494
381 static PyObject *dirstate_item_set_untracked(dirstateItemObject *self)
495 static PyObject *dirstate_item_set_untracked(dirstateItemObject *self)
382 {
496 {
383 if (self->state == 'm') {
497 self->flags &= ~dirstate_flag_wc_tracked;
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';
391 self->mode = 0;
498 self->mode = 0;
392 self->mtime = 0;
499 self->mtime = 0;
500 self->size = 0;
393 Py_RETURN_NONE;
501 Py_RETURN_NONE;
394 }
502 }
395
503
@@ -713,17 +821,19 b' static PyObject *nonnormalotherparentent'
713 }
821 }
714 t = (dirstateItemObject *)v;
822 t = (dirstateItemObject *)v;
715
823
716 if (t->state == 'n' && t->size == -2) {
824 if (dirstate_item_c_from_p2(t)) {
717 if (PySet_Add(otherpset, fname) == -1) {
825 if (PySet_Add(otherpset, fname) == -1) {
718 goto bail;
826 goto bail;
719 }
827 }
720 }
828 }
721
829 if (!(t->flags & dirstate_flag_wc_tracked) ||
722 if (t->state == 'n' && t->mtime != -1) {
830 !(t->flags &
723 continue;
831 (dirstate_flag_p1_tracked | dirstate_flag_p2_tracked)) ||
724 }
832 (t->flags &
725 if (PySet_Add(nonnset, fname) == -1) {
833 (dirstate_flag_possibly_dirty | dirstate_flag_merged))) {
726 goto bail;
834 if (PySet_Add(nonnset, fname) == -1) {
835 goto bail;
836 }
727 }
837 }
728 }
838 }
729
839
@@ -820,10 +930,10 b' static PyObject *pack_dirstate(PyObject '
820 }
930 }
821 tuple = (dirstateItemObject *)v;
931 tuple = (dirstateItemObject *)v;
822
932
823 state = tuple->state;
933 state = dirstate_item_c_v1_state(tuple);
824 mode = tuple->mode;
934 mode = dirstate_item_c_v1_mode(tuple);
825 size = tuple->size;
935 size = dirstate_item_c_v1_size(tuple);
826 mtime = tuple->mtime;
936 mtime = dirstate_item_c_v1_mtime(tuple);
827 if (state == 'n' && mtime == now) {
937 if (state == 'n' && mtime == now) {
828 /* See pure/parsers.py:pack_dirstate for why we do
938 /* See pure/parsers.py:pack_dirstate for why we do
829 * this. */
939 * this. */
@@ -24,13 +24,22 b''
24 /* clang-format off */
24 /* clang-format off */
25 typedef struct {
25 typedef struct {
26 PyObject_HEAD
26 PyObject_HEAD
27 char state;
27 char flags;
28 int mode;
28 int mode;
29 int size;
29 int size;
30 int mtime;
30 int mtime;
31 } dirstateItemObject;
31 } dirstateItemObject;
32 /* clang-format on */
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 extern PyTypeObject dirstateItemType;
43 extern PyTypeObject dirstateItemType;
35 #define dirstate_tuple_check(op) (Py_TYPE(op) == &dirstateItemType)
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