Show More
@@ -52,37 +52,32 b' static PyObject *dirstate_item_new(PyTyp' | |||
|
52 | 52 | dirstateItemObject *t; |
|
53 | 53 | int wc_tracked; |
|
54 | 54 | int p1_tracked; |
|
55 |
int p2_ |
|
|
56 | int merged; | |
|
57 | int clean_p1; | |
|
58 | int clean_p2; | |
|
59 | int possibly_dirty; | |
|
55 | int p2_info; | |
|
56 | int has_meaningful_data; | |
|
57 | int has_meaningful_mtime; | |
|
58 | int mode; | |
|
59 | int size; | |
|
60 | int mtime; | |
|
60 | 61 | PyObject *parentfiledata; |
|
61 | 62 | static char *keywords_name[] = { |
|
62 | "wc_tracked", "p1_tracked", "p2_tracked", | |
|
63 | "merged", "clean_p1", "clean_p2", | |
|
64 | "possibly_dirty", "parentfiledata", NULL, | |
|
63 | "wc_tracked", | |
|
64 | "p1_tracked", | |
|
65 | "p2_info", | |
|
66 | "has_meaningful_data", | |
|
67 | "has_meaningful_mtime", | |
|
68 | "parentfiledata", | |
|
69 | NULL, | |
|
65 | 70 | }; |
|
66 | 71 | wc_tracked = 0; |
|
67 | 72 | p1_tracked = 0; |
|
68 |
p2_ |
|
|
69 | merged = 0; | |
|
70 | clean_p1 = 0; | |
|
71 | clean_p2 = 0; | |
|
72 | possibly_dirty = 0; | |
|
73 | p2_info = 0; | |
|
74 | has_meaningful_mtime = 1; | |
|
75 | has_meaningful_data = 1; | |
|
73 | 76 | parentfiledata = Py_None; |
|
74 |
if (!PyArg_ParseTupleAndKeywords( |
|
|
75 | &wc_tracked, &p1_tracked, &p2_tracked, | |
|
76 | &merged, &clean_p1, &clean_p2, | |
|
77 | &possibly_dirty, &parentfiledata | |
|
78 | ||
|
79 | )) { | |
|
80 | return NULL; | |
|
81 | } | |
|
82 | if (merged && (clean_p1 || clean_p2)) { | |
|
83 | PyErr_SetString(PyExc_RuntimeError, | |
|
84 | "`merged` argument incompatible with " | |
|
85 | "`clean_p1`/`clean_p2`"); | |
|
77 | if (!PyArg_ParseTupleAndKeywords( | |
|
78 | args, kwds, "|iiiiiO", keywords_name, &wc_tracked, &p1_tracked, | |
|
79 | &p2_info, &has_meaningful_data, &has_meaningful_mtime, | |
|
80 | &parentfiledata)) { | |
|
86 | 81 | return NULL; |
|
87 | 82 | } |
|
88 | 83 | t = (dirstateItemObject *)subtype->tp_alloc(subtype, 1); |
@@ -97,24 +92,10 b' static PyObject *dirstate_item_new(PyTyp' | |||
|
97 | 92 | if (p1_tracked) { |
|
98 | 93 | t->flags |= dirstate_flag_p1_tracked; |
|
99 | 94 | } |
|
100 |
if (p2_ |
|
|
101 |
t->flags |= dirstate_flag_p2_ |
|
|
102 | } | |
|
103 | if (possibly_dirty) { | |
|
104 | t->flags |= dirstate_flag_possibly_dirty; | |
|
105 | } | |
|
106 | if (merged) { | |
|
107 | t->flags |= dirstate_flag_merged; | |
|
95 | if (p2_info) { | |
|
96 | t->flags |= dirstate_flag_p2_info; | |
|
108 | 97 | } |
|
109 | if (clean_p1) { | |
|
110 | t->flags |= dirstate_flag_clean_p1; | |
|
111 | } | |
|
112 | if (clean_p2) { | |
|
113 | t->flags |= dirstate_flag_clean_p2; | |
|
114 | } | |
|
115 | t->mode = 0; | |
|
116 | t->size = dirstate_v1_nonnormal; | |
|
117 | t->mtime = ambiguous_time; | |
|
98 | ||
|
118 | 99 | if (parentfiledata != Py_None) { |
|
119 | 100 | if (!PyTuple_CheckExact(parentfiledata)) { |
|
120 | 101 | PyErr_SetString( |
@@ -122,12 +103,26 b' static PyObject *dirstate_item_new(PyTyp' | |||
|
122 | 103 | "parentfiledata should be a Tuple or None"); |
|
123 | 104 | return NULL; |
|
124 | 105 | } |
|
125 | t->mode = | |
|
126 |
|
|
|
127 | t->size = | |
|
128 | (int)PyLong_AsLong(PyTuple_GetItem(parentfiledata, 1)); | |
|
129 | t->mtime = | |
|
130 | (int)PyLong_AsLong(PyTuple_GetItem(parentfiledata, 2)); | |
|
106 | mode = (int)PyLong_AsLong(PyTuple_GetItem(parentfiledata, 0)); | |
|
107 | size = (int)PyLong_AsLong(PyTuple_GetItem(parentfiledata, 1)); | |
|
108 | mtime = (int)PyLong_AsLong(PyTuple_GetItem(parentfiledata, 2)); | |
|
109 | } else { | |
|
110 | has_meaningful_data = 0; | |
|
111 | has_meaningful_mtime = 0; | |
|
112 | } | |
|
113 | if (has_meaningful_data) { | |
|
114 | t->flags |= dirstate_flag_has_meaningful_data; | |
|
115 | t->mode = mode; | |
|
116 | t->size = size; | |
|
117 | } else { | |
|
118 | t->mode = 0; | |
|
119 | t->size = 0; | |
|
120 | } | |
|
121 | if (has_meaningful_mtime) { | |
|
122 | t->flags |= dirstate_flag_has_meaningful_mtime; | |
|
123 | t->mtime = mtime; | |
|
124 | } else { | |
|
125 | t->mtime = 0; | |
|
131 | 126 | } |
|
132 | 127 | return (PyObject *)t; |
|
133 | 128 | } |
@@ -142,12 +137,20 b' static inline bool dirstate_item_c_track' | |||
|
142 | 137 | return (self->flags & dirstate_flag_wc_tracked); |
|
143 | 138 | } |
|
144 | 139 | |
|
140 | static inline bool dirstate_item_c_any_tracked(dirstateItemObject *self) | |
|
141 | { | |
|
142 | const unsigned char mask = dirstate_flag_wc_tracked | | |
|
143 | dirstate_flag_p1_tracked | | |
|
144 | dirstate_flag_p2_info; | |
|
145 | return (self->flags & mask); | |
|
146 | } | |
|
147 | ||
|
145 | 148 | static inline bool dirstate_item_c_added(dirstateItemObject *self) |
|
146 | 149 | { |
|
147 | unsigned char mask = | |
|
150 | const unsigned char mask = | |
|
148 | 151 | (dirstate_flag_wc_tracked | dirstate_flag_p1_tracked | |
|
149 |
dirstate_flag_p2_ |
|
|
150 | unsigned char target = dirstate_flag_wc_tracked; | |
|
152 | dirstate_flag_p2_info); | |
|
153 | const unsigned char target = dirstate_flag_wc_tracked; | |
|
151 | 154 | return (self->flags & mask) == target; |
|
152 | 155 | } |
|
153 | 156 | |
@@ -157,21 +160,21 b' static inline bool dirstate_item_c_remov' | |||
|
157 | 160 | return false; |
|
158 | 161 | } |
|
159 | 162 | return (self->flags & |
|
160 |
(dirstate_flag_p1_tracked | dirstate_flag_p2_ |
|
|
163 | (dirstate_flag_p1_tracked | dirstate_flag_p2_info)); | |
|
161 | 164 | } |
|
162 | 165 | |
|
163 | 166 | static inline bool dirstate_item_c_merged(dirstateItemObject *self) |
|
164 | 167 | { |
|
165 | 168 | return ((self->flags & dirstate_flag_wc_tracked) && |
|
166 |
(self->flags & dirstate_flag_ |
|
|
169 | (self->flags & dirstate_flag_p1_tracked) && | |
|
170 | (self->flags & dirstate_flag_p2_info)); | |
|
167 | 171 | } |
|
168 | 172 | |
|
169 | 173 | static inline bool dirstate_item_c_from_p2(dirstateItemObject *self) |
|
170 | 174 | { |
|
171 | if (!dirstate_item_c_tracked(self)) { | |
|
172 | return false; | |
|
173 | } | |
|
174 | return (self->flags & dirstate_flag_clean_p2); | |
|
175 | return ((self->flags & dirstate_flag_wc_tracked) && | |
|
176 | !(self->flags & dirstate_flag_p1_tracked) && | |
|
177 | (self->flags & dirstate_flag_p2_info)); | |
|
175 | 178 | } |
|
176 | 179 | |
|
177 | 180 | static inline char dirstate_item_c_v1_state(dirstateItemObject *self) |
@@ -189,29 +192,32 b' static inline char dirstate_item_c_v1_st' | |||
|
189 | 192 | |
|
190 | 193 | static inline int dirstate_item_c_v1_mode(dirstateItemObject *self) |
|
191 | 194 | { |
|
195 | if (self->flags & dirstate_flag_has_meaningful_data) { | |
|
192 | 196 | return self->mode; |
|
197 | } else { | |
|
198 | return 0; | |
|
199 | } | |
|
193 | 200 | } |
|
194 | 201 | |
|
195 | 202 | static inline int dirstate_item_c_v1_size(dirstateItemObject *self) |
|
196 | 203 | { |
|
197 | if (dirstate_item_c_removed(self) && | |
|
198 |
(self->flags & dirstate_flag_ |
|
|
204 | if (!(self->flags & dirstate_flag_wc_tracked) && | |
|
205 | (self->flags & dirstate_flag_p2_info)) { | |
|
206 | if (self->flags & dirstate_flag_p1_tracked) { | |
|
199 | 207 | return dirstate_v1_nonnormal; |
|
200 | } else if (dirstate_item_c_removed(self) && | |
|
201 | (self->flags & dirstate_flag_clean_p2)) { | |
|
208 | } else { | |
|
202 | 209 | return dirstate_v1_from_p2; |
|
210 | } | |
|
203 | 211 | } else if (dirstate_item_c_removed(self)) { |
|
204 | 212 | return 0; |
|
205 | } else if (dirstate_item_c_merged(self)) { | |
|
213 | } else if (self->flags & dirstate_flag_p2_info) { | |
|
206 | 214 | return dirstate_v1_from_p2; |
|
207 | 215 | } else if (dirstate_item_c_added(self)) { |
|
208 | 216 | return dirstate_v1_nonnormal; |
|
209 | } else if (dirstate_item_c_from_p2(self)) { | |
|
210 | return dirstate_v1_from_p2; | |
|
211 | } else if (self->flags & dirstate_flag_possibly_dirty) { | |
|
212 | return self->size; /* NON NORMAL ? */ | |
|
217 | } else if (self->flags & dirstate_flag_has_meaningful_data) { | |
|
218 | return self->size; | |
|
213 | 219 | } else { |
|
214 | return self->size; | |
|
220 | return dirstate_v1_nonnormal; | |
|
215 | 221 | } |
|
216 | 222 | } |
|
217 | 223 | |
@@ -219,13 +225,10 b' static inline int dirstate_item_c_v1_mti' | |||
|
219 | 225 | { |
|
220 | 226 | if (dirstate_item_c_removed(self)) { |
|
221 | 227 | return 0; |
|
222 |
} else if (self->flags & dirstate_flag_ |
|
|
223 | return ambiguous_time; | |
|
224 | } else if (dirstate_item_c_merged(self)) { | |
|
225 | return ambiguous_time; | |
|
226 | } else if (dirstate_item_c_added(self)) { | |
|
227 | return ambiguous_time; | |
|
228 | } else if (dirstate_item_c_from_p2(self)) { | |
|
228 | } else if (!(self->flags & dirstate_flag_has_meaningful_mtime) || | |
|
229 | !(self->flags & dirstate_flag_p1_tracked) || | |
|
230 | !(self->flags & dirstate_flag_wc_tracked) || | |
|
231 | (self->flags & dirstate_flag_p2_info)) { | |
|
229 | 232 | return ambiguous_time; |
|
230 | 233 | } else { |
|
231 | 234 | return self->mtime; |
@@ -278,58 +281,43 b' dirstate_item_from_v1_data(char state, i' | |||
|
278 | 281 | if (!t) { |
|
279 | 282 | return NULL; |
|
280 | 283 | } |
|
281 | ||
|
282 | if (state == 'm') { | |
|
283 | t->flags = | |
|
284 | (dirstate_flag_wc_tracked | dirstate_flag_p1_tracked | | |
|
285 | dirstate_flag_p2_tracked | dirstate_flag_merged); | |
|
286 | t->mode = 0; | |
|
287 | t->size = dirstate_v1_from_p2; | |
|
288 | t->mtime = ambiguous_time; | |
|
289 | } else if (state == 'a') { | |
|
290 | t->flags = dirstate_flag_wc_tracked; | |
|
291 | t->mode = 0; | |
|
292 | t->size = dirstate_v1_nonnormal; | |
|
293 | t->mtime = ambiguous_time; | |
|
294 | } else if (state == 'r') { | |
|
284 | t->flags = 0; | |
|
295 | 285 |
|
|
296 | 286 |
|
|
297 | 287 |
|
|
288 | ||
|
289 | if (state == 'm') { | |
|
290 | t->flags = (dirstate_flag_wc_tracked | | |
|
291 | dirstate_flag_p1_tracked | dirstate_flag_p2_info); | |
|
292 | } else if (state == 'a') { | |
|
293 | t->flags = dirstate_flag_wc_tracked; | |
|
294 | } else if (state == 'r') { | |
|
298 | 295 | if (size == dirstate_v1_nonnormal) { |
|
299 | 296 | t->flags = |
|
300 |
|
|
|
301 | dirstate_flag_p2_tracked | dirstate_flag_merged); | |
|
297 | dirstate_flag_p1_tracked | dirstate_flag_p2_info; | |
|
302 | 298 | } else if (size == dirstate_v1_from_p2) { |
|
303 | t->flags = | |
|
304 | (dirstate_flag_p2_tracked | dirstate_flag_clean_p2); | |
|
299 | t->flags = dirstate_flag_p2_info; | |
|
305 | 300 | } else { |
|
306 | 301 | t->flags = dirstate_flag_p1_tracked; |
|
307 | 302 | } |
|
308 | 303 | } else if (state == 'n') { |
|
309 | 304 | if (size == dirstate_v1_from_p2) { |
|
310 | 305 | t->flags = |
|
311 |
|
|
|
312 | dirstate_flag_p2_tracked | dirstate_flag_clean_p2); | |
|
313 | t->mode = 0; | |
|
314 | t->size = dirstate_v1_from_p2; | |
|
315 | t->mtime = ambiguous_time; | |
|
306 | dirstate_flag_wc_tracked | dirstate_flag_p2_info; | |
|
316 | 307 | } else if (size == dirstate_v1_nonnormal) { |
|
317 | t->flags = (dirstate_flag_wc_tracked | | |
|
318 |
|
|
|
319 | dirstate_flag_possibly_dirty); | |
|
320 | t->mode = 0; | |
|
321 | t->size = dirstate_v1_nonnormal; | |
|
322 | t->mtime = ambiguous_time; | |
|
308 | t->flags = | |
|
309 | dirstate_flag_wc_tracked | dirstate_flag_p1_tracked; | |
|
323 | 310 | } else if (mtime == ambiguous_time) { |
|
324 | 311 | t->flags = (dirstate_flag_wc_tracked | |
|
325 | 312 | dirstate_flag_p1_tracked | |
|
326 |
dirstate_flag_ |
|
|
313 | dirstate_flag_has_meaningful_data); | |
|
327 | 314 | t->mode = mode; |
|
328 | 315 | t->size = size; |
|
329 | t->mtime = 0; | |
|
330 | 316 | } else { |
|
331 | 317 | t->flags = (dirstate_flag_wc_tracked | |
|
332 |
dirstate_flag_p1_tracked |
|
|
318 | dirstate_flag_p1_tracked | | |
|
319 | dirstate_flag_has_meaningful_data | | |
|
320 | dirstate_flag_has_meaningful_mtime); | |
|
333 | 321 | t->mode = mode; |
|
334 | 322 | t->size = size; |
|
335 | 323 | t->mtime = mtime; |
@@ -371,8 +359,8 b' static PyObject *dirstate_item_new_added' | |||
|
371 | 359 | } |
|
372 | 360 | t->flags = dirstate_flag_wc_tracked; |
|
373 | 361 | t->mode = 0; |
|
374 | t->size = dirstate_v1_nonnormal; | |
|
375 |
t->mtime = |
|
|
362 | t->size = 0; | |
|
363 | t->mtime = 0; | |
|
376 | 364 | return (PyObject *)t; |
|
377 | 365 | }; |
|
378 | 366 | |
@@ -387,10 +375,10 b' static PyObject *dirstate_item_new_merge' | |||
|
387 | 375 | return NULL; |
|
388 | 376 | } |
|
389 | 377 | t->flags = (dirstate_flag_wc_tracked | dirstate_flag_p1_tracked | |
|
390 |
dirstate_flag_p2_ |
|
|
378 | dirstate_flag_p2_info); | |
|
391 | 379 | t->mode = 0; |
|
392 | t->size = dirstate_v1_from_p2; | |
|
393 |
t->mtime = |
|
|
380 | t->size = 0; | |
|
381 | t->mtime = 0; | |
|
394 | 382 | return (PyObject *)t; |
|
395 | 383 | }; |
|
396 | 384 | |
@@ -406,11 +394,10 b' static PyObject *dirstate_item_new_from_' | |||
|
406 | 394 | if (!t) { |
|
407 | 395 | return NULL; |
|
408 | 396 | } |
|
409 |
t->flags = |
|
|
410 | dirstate_flag_clean_p2); | |
|
397 | t->flags = dirstate_flag_wc_tracked | dirstate_flag_p2_info; | |
|
411 | 398 | t->mode = 0; |
|
412 | t->size = dirstate_v1_from_p2; | |
|
413 |
t->mtime = |
|
|
399 | t->size = 0; | |
|
400 | t->mtime = 0; | |
|
414 | 401 | return (PyObject *)t; |
|
415 | 402 | }; |
|
416 | 403 | |
@@ -426,11 +413,10 b' static PyObject *dirstate_item_new_possi' | |||
|
426 | 413 | if (!t) { |
|
427 | 414 | return NULL; |
|
428 | 415 | } |
|
429 |
t->flags = |
|
|
430 | dirstate_flag_possibly_dirty); | |
|
416 | t->flags = dirstate_flag_wc_tracked | dirstate_flag_p1_tracked; | |
|
431 | 417 | t->mode = 0; |
|
432 | t->size = dirstate_v1_nonnormal; | |
|
433 |
t->mtime = |
|
|
418 | t->size = 0; | |
|
419 | t->mtime = 0; | |
|
434 | 420 | return (PyObject *)t; |
|
435 | 421 | }; |
|
436 | 422 | |
@@ -462,7 +448,7 b' static PyObject *dirstate_item_new_norma' | |||
|
462 | 448 | to make sure it is correct. */ |
|
463 | 449 | static PyObject *dirstate_item_set_possibly_dirty(dirstateItemObject *self) |
|
464 | 450 | { |
|
465 |
self->flags |
|
|
451 | self->flags &= ~dirstate_flag_has_meaningful_mtime; | |
|
466 | 452 | Py_RETURN_NONE; |
|
467 | 453 | } |
|
468 | 454 | |
@@ -474,7 +460,9 b' static PyObject *dirstate_item_set_clean' | |||
|
474 | 460 | if (!PyArg_ParseTuple(args, "iii", &mode, &size, &mtime)) { |
|
475 | 461 | return NULL; |
|
476 | 462 | } |
|
477 |
self->flags = dirstate_flag_wc_tracked | dirstate_flag_p1_tracked |
|
|
463 | self->flags = dirstate_flag_wc_tracked | dirstate_flag_p1_tracked | | |
|
464 | dirstate_flag_has_meaningful_data | | |
|
465 | dirstate_flag_has_meaningful_mtime; | |
|
478 | 466 | self->mode = mode; |
|
479 | 467 | self->size = size; |
|
480 | 468 | self->mtime = mtime; |
@@ -484,11 +472,7 b' static PyObject *dirstate_item_set_clean' | |||
|
484 | 472 | static PyObject *dirstate_item_set_tracked(dirstateItemObject *self) |
|
485 | 473 | { |
|
486 | 474 | self->flags |= dirstate_flag_wc_tracked; |
|
487 |
self->flags |
|
|
488 | /* size = None on the python size turn into size = NON_NORMAL when | |
|
489 | * accessed. So the next line is currently required, but a some future | |
|
490 | * clean up would be welcome. */ | |
|
491 | self->size = dirstate_v1_nonnormal; | |
|
475 | self->flags &= ~dirstate_flag_has_meaningful_mtime; | |
|
492 | 476 | Py_RETURN_NONE; |
|
493 | 477 | } |
|
494 | 478 | |
@@ -503,22 +487,13 b' static PyObject *dirstate_item_set_untra' | |||
|
503 | 487 | |
|
504 | 488 | static PyObject *dirstate_item_drop_merge_data(dirstateItemObject *self) |
|
505 | 489 | { |
|
506 | if (dirstate_item_c_merged(self) || dirstate_item_c_from_p2(self)) { | |
|
507 | if (dirstate_item_c_merged(self)) { | |
|
508 | self->flags |= dirstate_flag_p1_tracked; | |
|
509 | } else { | |
|
510 | self->flags &= ~dirstate_flag_p1_tracked; | |
|
511 | } | |
|
512 | self->flags &= | |
|
513 | ~(dirstate_flag_merged | dirstate_flag_clean_p1 | | |
|
514 | dirstate_flag_clean_p2 | dirstate_flag_p2_tracked); | |
|
515 | self->flags |= dirstate_flag_possibly_dirty; | |
|
490 | if (self->flags & dirstate_flag_p2_info) { | |
|
491 | self->flags &= ~(dirstate_flag_p2_info | | |
|
492 | dirstate_flag_has_meaningful_data | | |
|
493 | dirstate_flag_has_meaningful_mtime); | |
|
516 | 494 | self->mode = 0; |
|
517 | 495 | self->mtime = 0; |
|
518 | /* size = None on the python size turn into size = NON_NORMAL | |
|
519 | * when accessed. So the next line is currently required, but a | |
|
520 | * some future clean up would be welcome. */ | |
|
521 | self->size = dirstate_v1_nonnormal; | |
|
496 | self->size = 0; | |
|
522 | 497 | } |
|
523 | 498 | Py_RETURN_NONE; |
|
524 | 499 | } |
@@ -624,11 +599,9 b' static PyObject *dirstate_item_get_maybe' | |||
|
624 | 599 | { |
|
625 | 600 | if (!(self->flags & dirstate_flag_wc_tracked)) { |
|
626 | 601 | Py_RETURN_FALSE; |
|
627 | } else if (dirstate_item_c_added(self)) { | |
|
602 | } else if (!(self->flags & dirstate_flag_p1_tracked)) { | |
|
628 | 603 | Py_RETURN_FALSE; |
|
629 |
} else if (self->flags & dirstate_flag_ |
|
|
630 | Py_RETURN_FALSE; | |
|
631 | } else if (self->flags & dirstate_flag_clean_p2) { | |
|
604 | } else if (self->flags & dirstate_flag_p2_info) { | |
|
632 | 605 | Py_RETURN_FALSE; |
|
633 | 606 | } else { |
|
634 | 607 | Py_RETURN_TRUE; |
@@ -637,10 +610,7 b' static PyObject *dirstate_item_get_maybe' | |||
|
637 | 610 | |
|
638 | 611 | static PyObject *dirstate_item_get_any_tracked(dirstateItemObject *self) |
|
639 | 612 | { |
|
640 | unsigned char mask = dirstate_flag_wc_tracked | | |
|
641 | dirstate_flag_p1_tracked | | |
|
642 | dirstate_flag_p2_tracked; | |
|
643 | if ((self->flags & mask) != 0) { | |
|
613 | if (dirstate_item_c_any_tracked(self)) { | |
|
644 | 614 | Py_RETURN_TRUE; |
|
645 | 615 | } else { |
|
646 | 616 | Py_RETURN_FALSE; |
@@ -33,11 +33,9 b' typedef struct {' | |||
|
33 | 33 | |
|
34 | 34 | static const unsigned char dirstate_flag_wc_tracked = 1; |
|
35 | 35 | static const unsigned char dirstate_flag_p1_tracked = 1 << 1; |
|
36 |
static const unsigned char dirstate_flag_p2_ |
|
|
37 |
static const unsigned char dirstate_flag_ |
|
|
38 |
static const unsigned char dirstate_flag_ |
|
|
39 | static const unsigned char dirstate_flag_clean_p1 = 1 << 5; | |
|
40 | static const unsigned char dirstate_flag_clean_p2 = 1 << 6; | |
|
36 | static const unsigned char dirstate_flag_p2_info = 1 << 2; | |
|
37 | static const unsigned char dirstate_flag_has_meaningful_data = 1 << 3; | |
|
38 | static const unsigned char dirstate_flag_has_meaningful_mtime = 1 << 4; | |
|
41 | 39 | |
|
42 | 40 | extern PyTypeObject dirstateItemType; |
|
43 | 41 | #define dirstate_tuple_check(op) (Py_TYPE(op) == &dirstateItemType) |
@@ -137,14 +137,7 b' class _dirstatemapcommon(object):' | |||
|
137 | 137 | if entry is None: |
|
138 | 138 | self._dirs_incr(filename) |
|
139 | 139 | entry = DirstateItem( |
|
140 | p1_tracked=False, | |
|
141 | p2_tracked=False, | |
|
142 | 140 | wc_tracked=True, |
|
143 | merged=False, | |
|
144 | clean_p1=False, | |
|
145 | clean_p2=False, | |
|
146 | possibly_dirty=False, | |
|
147 | parentfiledata=None, | |
|
148 | 141 | ) |
|
149 | 142 | |
|
150 | 143 | self._insert_entry(filename, entry) |
@@ -208,37 +201,20 b' class _dirstatemapcommon(object):' | |||
|
208 | 201 | self._drop_entry(filename) |
|
209 | 202 | self._dirs_decr(filename, old_entry=old_entry) |
|
210 | 203 | return |
|
211 | elif merged: | |
|
212 | pass | |
|
213 | elif not (p1_tracked or p2_tracked) and wc_tracked: | |
|
214 | pass # file is added, nothing special to adjust | |
|
215 | elif (p1_tracked or p2_tracked) and not wc_tracked: | |
|
216 | pass | |
|
217 | elif clean_p2 and wc_tracked: | |
|
218 | pass | |
|
219 | elif not p1_tracked and p2_tracked and wc_tracked: | |
|
220 | clean_p2 = True | |
|
221 | elif possibly_dirty: | |
|
222 | pass | |
|
223 | elif wc_tracked: | |
|
224 | # this is a "normal" file | |
|
225 | if parentfiledata is None: | |
|
226 | msg = b'failed to pass parentfiledata for a normal file: %s' | |
|
227 | msg %= filename | |
|
228 | raise error.ProgrammingError(msg) | |
|
229 | else: | |
|
230 | assert False, 'unreachable' | |
|
204 | ||
|
205 | p2_info = merged or clean_p2 | |
|
206 | if merged: | |
|
207 | assert p1_tracked | |
|
208 | ||
|
209 | has_meaningful_mtime = not possibly_dirty | |
|
231 | 210 | |
|
232 | 211 | old_entry = self._map.get(filename) |
|
233 | 212 | self._dirs_incr(filename, old_entry) |
|
234 | 213 | entry = DirstateItem( |
|
235 | 214 | wc_tracked=wc_tracked, |
|
236 | 215 | p1_tracked=p1_tracked, |
|
237 |
p2_ |
|
|
238 | merged=merged, | |
|
239 | clean_p1=clean_p1, | |
|
240 | clean_p2=clean_p2, | |
|
241 | possibly_dirty=possibly_dirty, | |
|
216 | p2_info=p2_info, | |
|
217 | has_meaningful_mtime=has_meaningful_mtime, | |
|
242 | 218 | parentfiledata=parentfiledata, |
|
243 | 219 | ) |
|
244 | 220 | self._insert_entry(filename, entry) |
@@ -53,36 +53,32 b' class DirstateItem(object):' | |||
|
53 | 53 | # about file tracking |
|
54 | 54 | - wc_tracked: is the file tracked by the working copy |
|
55 | 55 | - p1_tracked: is the file tracked in working copy first parent |
|
56 | - p2_tracked: is the file tracked in working copy second parent | |
|
57 | ||
|
58 | # about what possible merge action related to this file | |
|
59 | - clean_p1: merge picked the file content from p1 | |
|
60 | - clean_p2: merge picked the file content from p2 | |
|
61 | - merged: file gather changes from both side. | |
|
56 | - p2_info: the file has been involved in some merge operation. Either | |
|
57 | because it was actually merged, or because the p2 version was | |
|
58 | ahead, or because some renamed moved it there. In either case | |
|
59 | `hg status` will want it displayed as modified. | |
|
62 | 60 | |
|
63 | 61 | # about the file state expected from p1 manifest: |
|
64 | 62 | - mode: the file mode in p1 |
|
65 | 63 | - size: the file size in p1 |
|
66 | 64 | |
|
65 | These value can be set to None, which mean we don't have a meaningful value | |
|
66 | to compare with. Either because we don't really care about them as there | |
|
67 | `status` is known without having to look at the disk or because we don't | |
|
68 | know these right now and a full comparison will be needed to find out if | |
|
69 | the file is clean. | |
|
70 | ||
|
67 | 71 | # about the file state on disk last time we saw it: |
|
68 | 72 | - mtime: the last known clean mtime for the file. |
|
69 | 73 | |
|
70 | The last three item (mode, size and mtime) can be None if no meaningful (or | |
|
71 | trusted) value exists. | |
|
72 | ||
|
74 | This value can be set to None if no cachable state exist. Either because we | |
|
75 | do not care (see previous section) or because we could not cache something | |
|
76 | yet. | |
|
73 | 77 | """ |
|
74 | 78 | |
|
75 | 79 | _wc_tracked = attr.ib() |
|
76 | 80 | _p1_tracked = attr.ib() |
|
77 |
_p2_ |
|
|
78 | # the three item above should probably be combined | |
|
79 | # | |
|
80 | # However it is unclear if they properly cover some of the most advanced | |
|
81 | # merge case. So we should probably wait on this to be settled. | |
|
82 | _merged = attr.ib() | |
|
83 | _clean_p1 = attr.ib() | |
|
84 | _clean_p2 = attr.ib() | |
|
85 | _possibly_dirty = attr.ib() | |
|
81 | _p2_info = attr.ib() | |
|
86 | 82 | _mode = attr.ib() |
|
87 | 83 | _size = attr.ib() |
|
88 | 84 | _mtime = attr.ib() |
@@ -91,32 +87,25 b' class DirstateItem(object):' | |||
|
91 | 87 | self, |
|
92 | 88 | wc_tracked=False, |
|
93 | 89 | p1_tracked=False, |
|
94 |
p2_ |
|
|
95 | merged=False, | |
|
96 | clean_p1=False, | |
|
97 | clean_p2=False, | |
|
98 | possibly_dirty=False, | |
|
90 | p2_info=False, | |
|
91 | has_meaningful_data=True, | |
|
92 | has_meaningful_mtime=True, | |
|
99 | 93 | parentfiledata=None, |
|
100 | 94 | ): |
|
101 | if merged and (clean_p1 or clean_p2): | |
|
102 | msg = b'`merged` argument incompatible with `clean_p1`/`clean_p2`' | |
|
103 | raise error.ProgrammingError(msg) | |
|
104 | ||
|
105 | assert not (merged and not p1_tracked) | |
|
106 | 95 | self._wc_tracked = wc_tracked |
|
107 | 96 | self._p1_tracked = p1_tracked |
|
108 |
self._p2_ |
|
|
109 | self._merged = merged | |
|
110 | self._clean_p1 = clean_p1 | |
|
111 | self._clean_p2 = clean_p2 | |
|
112 | self._possibly_dirty = possibly_dirty | |
|
113 | if parentfiledata is None: | |
|
97 | self._p2_info = p2_info | |
|
98 | ||
|
114 | 99 |
|
|
115 | 100 |
|
|
116 | 101 |
|
|
117 | else: | |
|
102 | if parentfiledata is None: | |
|
103 | has_meaningful_mtime = False | |
|
104 | has_meaningful_data = False | |
|
105 | if has_meaningful_data: | |
|
118 | 106 | self._mode = parentfiledata[0] |
|
119 | 107 | self._size = parentfiledata[1] |
|
108 | if has_meaningful_mtime: | |
|
120 | 109 | self._mtime = parentfiledata[2] |
|
121 | 110 | |
|
122 | 111 | @classmethod |
@@ -125,11 +114,7 b' class DirstateItem(object):' | |||
|
125 | 114 | |
|
126 | 115 | Should eventually be removed |
|
127 | 116 | """ |
|
128 | instance = cls() | |
|
129 | instance._wc_tracked = True | |
|
130 | instance._p1_tracked = False | |
|
131 | instance._p2_tracked = False | |
|
132 | return instance | |
|
117 | return cls(wc_tracked=True) | |
|
133 | 118 | |
|
134 | 119 | @classmethod |
|
135 | 120 | def new_merged(cls): |
@@ -137,12 +122,7 b' class DirstateItem(object):' | |||
|
137 | 122 | |
|
138 | 123 | Should eventually be removed |
|
139 | 124 | """ |
|
140 | instance = cls() | |
|
141 | instance._wc_tracked = True | |
|
142 | instance._p1_tracked = True # might not be True because of rename ? | |
|
143 | instance._p2_tracked = True # might not be True because of rename ? | |
|
144 | instance._merged = True | |
|
145 | return instance | |
|
125 | return cls(wc_tracked=True, p1_tracked=True, p2_info=True) | |
|
146 | 126 | |
|
147 | 127 | @classmethod |
|
148 | 128 | def new_from_p2(cls): |
@@ -150,12 +130,7 b' class DirstateItem(object):' | |||
|
150 | 130 | |
|
151 | 131 | Should eventually be removed |
|
152 | 132 | """ |
|
153 | instance = cls() | |
|
154 | instance._wc_tracked = True | |
|
155 | instance._p1_tracked = False # might actually be True | |
|
156 | instance._p2_tracked = True | |
|
157 | instance._clean_p2 = True | |
|
158 | return instance | |
|
133 | return cls(wc_tracked=True, p2_info=True) | |
|
159 | 134 | |
|
160 | 135 | @classmethod |
|
161 | 136 | def new_possibly_dirty(cls): |
@@ -163,11 +138,7 b' class DirstateItem(object):' | |||
|
163 | 138 | |
|
164 | 139 | Should eventually be removed |
|
165 | 140 | """ |
|
166 | instance = cls() | |
|
167 | instance._wc_tracked = True | |
|
168 | instance._p1_tracked = True | |
|
169 | instance._possibly_dirty = True | |
|
170 | return instance | |
|
141 | return cls(wc_tracked=True, p1_tracked=True) | |
|
171 | 142 | |
|
172 | 143 | @classmethod |
|
173 | 144 | def new_normal(cls, mode, size, mtime): |
@@ -177,13 +148,11 b' class DirstateItem(object):' | |||
|
177 | 148 | """ |
|
178 | 149 | assert size != FROM_P2 |
|
179 | 150 | assert size != NONNORMAL |
|
180 |
|
|
|
181 |
|
|
|
182 |
|
|
|
183 | instance._mode = mode | |
|
184 | instance._size = size | |
|
185 | instance._mtime = mtime | |
|
186 | return instance | |
|
151 | return cls( | |
|
152 | wc_tracked=True, | |
|
153 | p1_tracked=True, | |
|
154 | parentfiledata=(mode, size, mtime), | |
|
155 | ) | |
|
187 | 156 | |
|
188 | 157 | @classmethod |
|
189 | 158 | def from_v1_data(cls, state, mode, size, mtime): |
@@ -197,25 +166,16 b' class DirstateItem(object):' | |||
|
197 | 166 | elif state == b'a': |
|
198 | 167 | return cls.new_added() |
|
199 | 168 | elif state == b'r': |
|
200 | instance = cls() | |
|
201 | instance._wc_tracked = False | |
|
202 | 169 | if size == NONNORMAL: |
|
203 |
|
|
|
204 |
|
|
|
205 | True # might not be True because of rename ? | |
|
206 | ) | |
|
207 | instance._p2_tracked = ( | |
|
208 | True # might not be True because of rename ? | |
|
209 | ) | |
|
170 | p1_tracked = True | |
|
171 | p2_info = True | |
|
210 | 172 | elif size == FROM_P2: |
|
211 |
|
|
|
212 |
|
|
|
213 | False # We actually don't know (file history) | |
|
214 | ) | |
|
215 | instance._p2_tracked = True | |
|
173 | p1_tracked = False | |
|
174 | p2_info = True | |
|
216 | 175 | else: |
|
217 |
|
|
|
218 | return instance | |
|
176 | p1_tracked = True | |
|
177 | p2_info = False | |
|
178 | return cls(p1_tracked=p1_tracked, p2_info=p2_info) | |
|
219 | 179 | elif state == b'n': |
|
220 | 180 | if size == FROM_P2: |
|
221 | 181 | return cls.new_from_p2() |
@@ -224,7 +184,6 b' class DirstateItem(object):' | |||
|
224 | 184 | elif mtime == AMBIGUOUS_TIME: |
|
225 | 185 | instance = cls.new_normal(mode, size, 42) |
|
226 | 186 | instance._mtime = None |
|
227 | instance._possibly_dirty = True | |
|
228 | 187 | return instance |
|
229 | 188 | else: |
|
230 | 189 | return cls.new_normal(mode, size, mtime) |
@@ -237,7 +196,7 b' class DirstateItem(object):' | |||
|
237 | 196 | This means the next status call will have to actually check its content |
|
238 | 197 | to make sure it is correct. |
|
239 | 198 | """ |
|
240 |
self._ |
|
|
199 | self._mtime = None | |
|
241 | 200 | |
|
242 | 201 | def set_clean(self, mode, size, mtime): |
|
243 | 202 | """mark a file as "clean" cancelling potential "possibly dirty call" |
@@ -249,10 +208,6 b' class DirstateItem(object):' | |||
|
249 | 208 | """ |
|
250 | 209 | self._wc_tracked = True |
|
251 | 210 | self._p1_tracked = True |
|
252 | self._p2_tracked = False # this might be wrong | |
|
253 | self._merged = False | |
|
254 | self._clean_p2 = False | |
|
255 | self._possibly_dirty = False | |
|
256 | 211 | self._mode = mode |
|
257 | 212 | self._size = size |
|
258 | 213 | self._mtime = mtime |
@@ -263,11 +218,11 b' class DirstateItem(object):' | |||
|
263 | 218 | This will ultimately be called by command like `hg add`. |
|
264 | 219 | """ |
|
265 | 220 | self._wc_tracked = True |
|
266 |
# `set_tracked` is replacing various `normallookup` call. So we |
|
|
267 | # "possibly dirty" to stay on the safe side. | |
|
221 | # `set_tracked` is replacing various `normallookup` call. So we mark | |
|
222 | # the files as needing lookup | |
|
268 | 223 | # |
|
269 | 224 | # Consider dropping this in the future in favor of something less broad. |
|
270 |
self._ |
|
|
225 | self._mtime = None | |
|
271 | 226 | |
|
272 | 227 | def set_untracked(self): |
|
273 | 228 | """mark a file as untracked in the working copy |
@@ -284,15 +239,8 b' class DirstateItem(object):' | |||
|
284 | 239 | |
|
285 | 240 | This is to be call by the dirstatemap code when the second parent is dropped |
|
286 | 241 | """ |
|
287 | if not (self.merged or self.from_p2): | |
|
288 | return | |
|
289 | self._p1_tracked = self.merged # why is this not already properly set ? | |
|
290 | ||
|
291 | self._merged = False | |
|
292 | self._clean_p1 = False | |
|
293 | self._clean_p2 = False | |
|
294 | self._p2_tracked = False | |
|
295 | self._possibly_dirty = True | |
|
242 | if self._p2_info: | |
|
243 | self._p2_info = False | |
|
296 | 244 | self._mode = None |
|
297 | 245 | self._size = None |
|
298 | 246 | self._mtime = None |
@@ -334,23 +282,21 b' class DirstateItem(object):' | |||
|
334 | 282 | @property |
|
335 | 283 | def any_tracked(self): |
|
336 | 284 | """True is the file is tracked anywhere (wc or parents)""" |
|
337 |
return self._wc_tracked or self._p1_tracked or self._p2_ |
|
|
285 | return self._wc_tracked or self._p1_tracked or self._p2_info | |
|
338 | 286 | |
|
339 | 287 | @property |
|
340 | 288 | def added(self): |
|
341 | 289 | """True if the file has been added""" |
|
342 |
return self._wc_tracked and not (self._p1_tracked or self._p2_ |
|
|
290 | return self._wc_tracked and not (self._p1_tracked or self._p2_info) | |
|
343 | 291 | |
|
344 | 292 | @property |
|
345 | 293 | def maybe_clean(self): |
|
346 | 294 | """True if the file has a chance to be in the "clean" state""" |
|
347 | 295 | if not self._wc_tracked: |
|
348 | 296 | return False |
|
349 |
elif self. |
|
|
297 | elif not self._p1_tracked: | |
|
350 | 298 | return False |
|
351 |
elif self._ |
|
|
352 | return False | |
|
353 | elif self._clean_p2: | |
|
299 | elif self._p2_info: | |
|
354 | 300 | return False |
|
355 | 301 | return True |
|
356 | 302 | |
@@ -360,7 +306,7 b' class DirstateItem(object):' | |||
|
360 | 306 | |
|
361 | 307 | Should only be set if a merge is in progress in the dirstate |
|
362 | 308 | """ |
|
363 |
return self._wc_tracked and self._ |
|
|
309 | return self._wc_tracked and self._p1_tracked and self._p2_info | |
|
364 | 310 | |
|
365 | 311 | @property |
|
366 | 312 | def from_p2(self): |
@@ -370,18 +316,16 b' class DirstateItem(object):' | |||
|
370 | 316 | |
|
371 | 317 | Should only be set if a merge is in progress in the dirstate |
|
372 | 318 | """ |
|
373 | if not self._wc_tracked: | |
|
374 | return False | |
|
375 | return self._clean_p2 | |
|
319 | return self._wc_tracked and (not self._p1_tracked) and self._p2_info | |
|
376 | 320 | |
|
377 | 321 | @property |
|
378 | 322 | def removed(self): |
|
379 | 323 | """True if the file has been removed""" |
|
380 |
return not self._wc_tracked and (self._p1_tracked or self._p2_ |
|
|
324 | return not self._wc_tracked and (self._p1_tracked or self._p2_info) | |
|
381 | 325 | |
|
382 | 326 | def v1_state(self): |
|
383 | 327 | """return a "state" suitable for v1 serialization""" |
|
384 | if not (self._p1_tracked or self._p2_tracked or self._wc_tracked): | |
|
328 | if not self.any_tracked: | |
|
385 | 329 | # the object has no state to record, this is -currently- |
|
386 | 330 | # unsupported |
|
387 | 331 | raise RuntimeError('untracked item') |
@@ -404,9 +348,9 b' class DirstateItem(object):' | |||
|
404 | 348 | # the object has no state to record, this is -currently- |
|
405 | 349 | # unsupported |
|
406 | 350 | raise RuntimeError('untracked item') |
|
407 |
elif self.removed and self._ |
|
|
351 | elif self.removed and self._p1_tracked and self._p2_info: | |
|
408 | 352 | return NONNORMAL |
|
409 |
elif self.removed and self. |
|
|
353 | elif self.removed and self._p2_info: | |
|
410 | 354 | return FROM_P2 |
|
411 | 355 | elif self.removed: |
|
412 | 356 | return 0 |
@@ -416,8 +360,8 b' class DirstateItem(object):' | |||
|
416 | 360 | return NONNORMAL |
|
417 | 361 | elif self.from_p2: |
|
418 | 362 | return FROM_P2 |
|
419 |
elif self._ |
|
|
420 | return self._size if self._size is not None else NONNORMAL | |
|
363 | elif self._size is None: | |
|
364 | return NONNORMAL | |
|
421 | 365 | else: |
|
422 | 366 | return self._size |
|
423 | 367 | |
@@ -429,16 +373,14 b' class DirstateItem(object):' | |||
|
429 | 373 | raise RuntimeError('untracked item') |
|
430 | 374 | elif self.removed: |
|
431 | 375 | return 0 |
|
432 |
elif self._ |
|
|
433 | return AMBIGUOUS_TIME | |
|
434 | elif self.merged: | |
|
376 | elif self._mtime is None: | |
|
435 | 377 | return AMBIGUOUS_TIME |
|
436 |
elif self. |
|
|
378 | elif self._p2_info: | |
|
437 | 379 | return AMBIGUOUS_TIME |
|
438 |
elif self. |
|
|
380 | elif not self._p1_tracked: | |
|
439 | 381 | return AMBIGUOUS_TIME |
|
440 | 382 | else: |
|
441 |
return self._mtime |
|
|
383 | return self._mtime | |
|
442 | 384 | |
|
443 | 385 | def need_delay(self, now): |
|
444 | 386 | """True if the stored mtime would be ambiguous with the current time""" |
@@ -16,21 +16,15 b' pub enum EntryState {' | |||
|
16 | 16 | #[derive(Debug, PartialEq, Copy, Clone)] |
|
17 | 17 | pub struct DirstateEntry { |
|
18 | 18 | flags: Flags, |
|
19 | mode: i32, | |
|
20 |
|
|
|
21 | mtime: i32, | |
|
19 | mode_size: Option<(i32, i32)>, | |
|
20 | mtime: Option<i32>, | |
|
22 | 21 | } |
|
23 | 22 | |
|
24 | 23 | bitflags! { |
|
25 |
|
|
|
24 | struct Flags: u8 { | |
|
26 | 25 | const WDIR_TRACKED = 1 << 0; |
|
27 | 26 | const P1_TRACKED = 1 << 1; |
|
28 |
const P2_ |
|
|
29 | const POSSIBLY_DIRTY = 1 << 3; | |
|
30 | const MERGED = 1 << 4; | |
|
31 | const CLEAN_P1 = 1 << 5; | |
|
32 | const CLEAN_P2 = 1 << 6; | |
|
33 | const ENTRYLESS_TREE_NODE = 1 << 7; | |
|
27 | const P2_INFO = 1 << 2; | |
|
34 | 28 | } |
|
35 | 29 | } |
|
36 | 30 | |
@@ -48,15 +42,19 b' pub const SIZE_NON_NORMAL: i32 = -1;' | |||
|
48 | 42 | |
|
49 | 43 | impl DirstateEntry { |
|
50 | 44 | pub fn new( |
|
51 | flags: Flags, | |
|
52 | mode_size_mtime: Option<(i32, i32, i32)>, | |
|
45 | wdir_tracked: bool, | |
|
46 | p1_tracked: bool, | |
|
47 | p2_info: bool, | |
|
48 | mode_size: Option<(i32, i32)>, | |
|
49 | mtime: Option<i32>, | |
|
53 | 50 | ) -> Self { |
|
54 | let (mode, size, mtime) = | |
|
55 | mode_size_mtime.unwrap_or((0, SIZE_NON_NORMAL, MTIME_UNSET)); | |
|
51 | let mut flags = Flags::empty(); | |
|
52 | flags.set(Flags::WDIR_TRACKED, wdir_tracked); | |
|
53 | flags.set(Flags::P1_TRACKED, p1_tracked); | |
|
54 | flags.set(Flags::P2_INFO, p2_info); | |
|
56 | 55 | Self { |
|
57 | 56 | flags, |
|
58 | mode, | |
|
59 | size, | |
|
57 | mode_size, | |
|
60 | 58 | mtime, |
|
61 | 59 | } |
|
62 | 60 | } |
@@ -75,12 +73,9 b' impl DirstateEntry {' | |||
|
75 | 73 | Self::new_possibly_dirty() |
|
76 | 74 | } else if mtime == MTIME_UNSET { |
|
77 | 75 | Self { |
|
78 | flags: Flags::WDIR_TRACKED | |
|
79 | | Flags::P1_TRACKED | |
|
80 | | Flags::POSSIBLY_DIRTY, | |
|
81 | mode, | |
|
82 | size, | |
|
83 | mtime: 0, | |
|
76 | flags: Flags::WDIR_TRACKED | Flags::P1_TRACKED, | |
|
77 | mode_size: Some((mode, size)), | |
|
78 | mtime: None, | |
|
84 | 79 | } |
|
85 | 80 | } else { |
|
86 | 81 | Self::new_normal(mode, size, mtime) |
@@ -89,18 +84,15 b' impl DirstateEntry {' | |||
|
89 | 84 | EntryState::Added => Self::new_added(), |
|
90 | 85 | EntryState::Removed => Self { |
|
91 | 86 | flags: if size == SIZE_NON_NORMAL { |
|
92 |
Flags::P1_TRACKED |
|
|
93 | | Flags::P2_TRACKED // might not be true because of rename ? | |
|
94 | | Flags::MERGED | |
|
87 | Flags::P1_TRACKED | Flags::P2_INFO | |
|
95 | 88 | } else if size == SIZE_FROM_OTHER_PARENT { |
|
96 | 89 | // We donβt know if P1_TRACKED should be set (file history) |
|
97 |
Flags::P2_ |
|
|
90 | Flags::P2_INFO | |
|
98 | 91 | } else { |
|
99 | 92 | Flags::P1_TRACKED |
|
100 | 93 | }, |
|
101 |
mode: |
|
|
102 |
|
|
|
103 | mtime: 0, | |
|
94 | mode_size: None, | |
|
95 | mtime: None, | |
|
104 | 96 | }, |
|
105 | 97 | EntryState::Merged => Self::new_merged(), |
|
106 | 98 | } |
@@ -109,30 +101,25 b' impl DirstateEntry {' | |||
|
109 | 101 | pub fn new_from_p2() -> Self { |
|
110 | 102 | Self { |
|
111 | 103 | // might be missing P1_TRACKED |
|
112 |
flags: Flags::WDIR_TRACKED | Flags::P2_ |
|
|
113 |
mode: |
|
|
114 | size: SIZE_FROM_OTHER_PARENT, | |
|
115 | mtime: MTIME_UNSET, | |
|
104 | flags: Flags::WDIR_TRACKED | Flags::P2_INFO, | |
|
105 | mode_size: None, | |
|
106 | mtime: None, | |
|
116 | 107 | } |
|
117 | 108 | } |
|
118 | 109 | |
|
119 | 110 | pub fn new_possibly_dirty() -> Self { |
|
120 | 111 | Self { |
|
121 | flags: Flags::WDIR_TRACKED | |
|
122 | | Flags::P1_TRACKED | |
|
123 | | Flags::POSSIBLY_DIRTY, | |
|
124 | mode: 0, | |
|
125 | size: SIZE_NON_NORMAL, | |
|
126 | mtime: MTIME_UNSET, | |
|
112 | flags: Flags::WDIR_TRACKED | Flags::P1_TRACKED, | |
|
113 | mode_size: None, | |
|
114 | mtime: None, | |
|
127 | 115 | } |
|
128 | 116 | } |
|
129 | 117 | |
|
130 | 118 | pub fn new_added() -> Self { |
|
131 | 119 | Self { |
|
132 | 120 | flags: Flags::WDIR_TRACKED, |
|
133 |
mode: |
|
|
134 |
|
|
|
135 | mtime: MTIME_UNSET, | |
|
121 | mode_size: None, | |
|
122 | mtime: None, | |
|
136 | 123 | } |
|
137 | 124 | } |
|
138 | 125 | |
@@ -140,20 +127,17 b' impl DirstateEntry {' | |||
|
140 | 127 | Self { |
|
141 | 128 | flags: Flags::WDIR_TRACKED |
|
142 | 129 | | Flags::P1_TRACKED // might not be true because of rename ? |
|
143 |
| Flags::P2_ |
|
|
144 | | Flags::MERGED, | |
|
145 |
m |
|
|
146 | size: SIZE_NON_NORMAL, | |
|
147 | mtime: MTIME_UNSET, | |
|
130 | | Flags::P2_INFO, // might not be true because of rename ? | |
|
131 | mode_size: None, | |
|
132 | mtime: None, | |
|
148 | 133 | } |
|
149 | 134 | } |
|
150 | 135 | |
|
151 | 136 | pub fn new_normal(mode: i32, size: i32, mtime: i32) -> Self { |
|
152 | 137 | Self { |
|
153 | 138 | flags: Flags::WDIR_TRACKED | Flags::P1_TRACKED, |
|
154 | mode, | |
|
155 |
|
|
|
156 | mtime, | |
|
139 | mode_size: Some((mode, size)), | |
|
140 | mtime: Some(mtime), | |
|
157 | 141 | } |
|
158 | 142 | } |
|
159 | 143 | |
@@ -169,36 +153,34 b' impl DirstateEntry {' | |||
|
169 | 153 | self.flags.contains(Flags::WDIR_TRACKED) |
|
170 | 154 | } |
|
171 | 155 | |
|
172 |
fn |
|
|
173 |
self.flags.intersects(Flags::P1_TRACKED | Flags::P2_ |
|
|
156 | fn in_either_parent(&self) -> bool { | |
|
157 | self.flags.intersects(Flags::P1_TRACKED | Flags::P2_INFO) | |
|
174 | 158 | } |
|
175 | 159 | |
|
176 | 160 | pub fn removed(&self) -> bool { |
|
177 | self.tracked_in_any_parent() | |
|
178 | && !self.flags.contains(Flags::WDIR_TRACKED) | |
|
161 | self.in_either_parent() && !self.flags.contains(Flags::WDIR_TRACKED) | |
|
179 | 162 | } |
|
180 | 163 | |
|
181 | 164 | pub fn merged(&self) -> bool { |
|
182 | self.flags.contains(Flags::WDIR_TRACKED | Flags::MERGED) | |
|
165 | self.flags | |
|
166 | .contains(Flags::WDIR_TRACKED | Flags::P1_TRACKED | Flags::P2_INFO) | |
|
183 | 167 | } |
|
184 | 168 | |
|
185 | 169 | pub fn added(&self) -> bool { |
|
186 | self.flags.contains(Flags::WDIR_TRACKED) | |
|
187 | && !self.tracked_in_any_parent() | |
|
170 | self.flags.contains(Flags::WDIR_TRACKED) && !self.in_either_parent() | |
|
188 | 171 | } |
|
189 | 172 | |
|
190 | 173 | pub fn from_p2(&self) -> bool { |
|
191 |
self.flags.contains(Flags::WDIR_TRACKED | Flags:: |
|
|
174 | self.flags.contains(Flags::WDIR_TRACKED | Flags::P2_INFO) | |
|
175 | && !self.flags.contains(Flags::P1_TRACKED) | |
|
192 | 176 | } |
|
193 | 177 | |
|
194 | 178 | pub fn maybe_clean(&self) -> bool { |
|
195 | 179 | if !self.flags.contains(Flags::WDIR_TRACKED) { |
|
196 | 180 | false |
|
197 |
} else if self. |
|
|
181 | } else if !self.flags.contains(Flags::P1_TRACKED) { | |
|
198 | 182 | false |
|
199 |
} else if self.flags.contains(Flags:: |
|
|
200 | false | |
|
201 | } else if self.flags.contains(Flags::CLEAN_P2) { | |
|
183 | } else if self.flags.contains(Flags::P2_INFO) { | |
|
202 | 184 | false |
|
203 | 185 | } else { |
|
204 | 186 | true |
@@ -207,11 +189,15 b' impl DirstateEntry {' | |||
|
207 | 189 | |
|
208 | 190 | pub fn any_tracked(&self) -> bool { |
|
209 | 191 | self.flags.intersects( |
|
210 |
Flags::WDIR_TRACKED | Flags::P1_TRACKED | Flags::P2_ |
|
|
192 | Flags::WDIR_TRACKED | Flags::P1_TRACKED | Flags::P2_INFO, | |
|
211 | 193 | ) |
|
212 | 194 | } |
|
213 | 195 | |
|
214 |
|
|
|
196 | fn v1_state(&self) -> EntryState { | |
|
197 | if !self.any_tracked() { | |
|
198 | // TODO: return an Option instead? | |
|
199 | panic!("Accessing v1_state of an untracked DirstateEntry") | |
|
200 | } | |
|
215 | 201 | if self.removed() { |
|
216 | 202 | EntryState::Removed |
|
217 | 203 | } else if self.merged() { |
@@ -223,14 +209,24 b' impl DirstateEntry {' | |||
|
223 | 209 | } |
|
224 | 210 | } |
|
225 | 211 | |
|
226 |
|
|
|
227 | self.mode | |
|
212 | fn v1_mode(&self) -> i32 { | |
|
213 | if let Some((mode, _size)) = self.mode_size { | |
|
214 | mode | |
|
215 | } else { | |
|
216 | 0 | |
|
217 | } | |
|
228 | 218 | } |
|
229 | 219 | |
|
230 |
|
|
|
231 | if self.removed() && self.flags.contains(Flags::MERGED) { | |
|
220 | fn v1_size(&self) -> i32 { | |
|
221 | if !self.any_tracked() { | |
|
222 | // TODO: return an Option instead? | |
|
223 | panic!("Accessing v1_size of an untracked DirstateEntry") | |
|
224 | } | |
|
225 | if self.removed() | |
|
226 | && self.flags.contains(Flags::P1_TRACKED | Flags::P2_INFO) | |
|
227 | { | |
|
232 | 228 | SIZE_NON_NORMAL |
|
233 |
} else if self.removed() && self.flags.contains(Flags:: |
|
|
229 | } else if self.removed() && self.flags.contains(Flags::P2_INFO) { | |
|
234 | 230 | SIZE_FROM_OTHER_PARENT |
|
235 | 231 | } else if self.removed() { |
|
236 | 232 | 0 |
@@ -240,87 +236,81 b' impl DirstateEntry {' | |||
|
240 | 236 | SIZE_NON_NORMAL |
|
241 | 237 | } else if self.from_p2() { |
|
242 | 238 | SIZE_FROM_OTHER_PARENT |
|
243 | } else if self.flags.contains(Flags::POSSIBLY_DIRTY) { | |
|
244 | self.size // TODO: SIZE_NON_NORMAL ? | |
|
239 | } else if let Some((_mode, size)) = self.mode_size { | |
|
240 | size | |
|
245 | 241 | } else { |
|
246 | self.size | |
|
242 | SIZE_NON_NORMAL | |
|
247 | 243 | } |
|
248 | 244 | } |
|
249 | 245 | |
|
250 |
|
|
|
246 | fn v1_mtime(&self) -> i32 { | |
|
247 | if !self.any_tracked() { | |
|
248 | // TODO: return an Option instead? | |
|
249 | panic!("Accessing v1_mtime of an untracked DirstateEntry") | |
|
250 | } | |
|
251 | 251 | if self.removed() { |
|
252 | 252 | 0 |
|
253 |
} else if self.flags.contains(Flags::P |
|
|
254 | MTIME_UNSET | |
|
255 | } else if self.merged() { | |
|
253 | } else if self.flags.contains(Flags::P2_INFO) { | |
|
256 | 254 | MTIME_UNSET |
|
257 |
} else if self. |
|
|
258 | MTIME_UNSET | |
|
259 | } else if self.from_p2() { | |
|
255 | } else if !self.flags.contains(Flags::P1_TRACKED) { | |
|
260 | 256 | MTIME_UNSET |
|
261 | 257 | } else { |
|
262 | self.mtime | |
|
258 | self.mtime.unwrap_or(MTIME_UNSET) | |
|
259 | } | |
|
260 | } | |
|
261 | ||
|
262 | // TODO: return `Option<EntryState>`? None when `!self.any_tracked` | |
|
263 | pub fn state(&self) -> EntryState { | |
|
264 | self.v1_state() | |
|
263 | 265 |
|
|
266 | ||
|
267 | // TODO: return Option? | |
|
268 | pub fn mode(&self) -> i32 { | |
|
269 | self.v1_mode() | |
|
270 | } | |
|
271 | ||
|
272 | // TODO: return Option? | |
|
273 | pub fn size(&self) -> i32 { | |
|
274 | self.v1_size() | |
|
275 | } | |
|
276 | ||
|
277 | // TODO: return Option? | |
|
278 | pub fn mtime(&self) -> i32 { | |
|
279 | self.v1_mtime() | |
|
264 | 280 | } |
|
265 | 281 | |
|
266 | 282 | pub fn drop_merge_data(&mut self) { |
|
267 |
if self.flags.contains(Flags:: |
|
|
268 |
|
|
|
269 | || self.flags.contains(Flags::MERGED) | |
|
270 | || self.flags.contains(Flags::P2_TRACKED) | |
|
271 | { | |
|
272 | if self.flags.contains(Flags::MERGED) { | |
|
273 | self.flags.insert(Flags::P1_TRACKED); | |
|
274 | } else { | |
|
275 | self.flags.remove(Flags::P1_TRACKED); | |
|
276 | } | |
|
277 | self.flags.remove( | |
|
278 | Flags::MERGED | |
|
279 | | Flags::CLEAN_P1 | |
|
280 | | Flags::CLEAN_P2 | |
|
281 | | Flags::P2_TRACKED, | |
|
282 | ); | |
|
283 | self.flags.insert(Flags::POSSIBLY_DIRTY); | |
|
284 | self.mode = 0; | |
|
285 | self.mtime = 0; | |
|
286 | // size = None on the python size turn into size = NON_NORMAL when | |
|
287 | // accessed. So the next line is currently required, but a some | |
|
288 | // future clean up would be welcome. | |
|
289 | self.size = SIZE_NON_NORMAL; | |
|
283 | if self.flags.contains(Flags::P2_INFO) { | |
|
284 | self.flags.remove(Flags::P2_INFO); | |
|
285 | self.mode_size = None; | |
|
286 | self.mtime = None; | |
|
290 | 287 | } |
|
291 | 288 | } |
|
292 | 289 | |
|
293 | 290 | pub fn set_possibly_dirty(&mut self) { |
|
294 | self.flags.insert(Flags::POSSIBLY_DIRTY) | |
|
291 | self.mtime = None | |
|
295 | 292 | } |
|
296 | 293 | |
|
297 | 294 | pub fn set_clean(&mut self, mode: i32, size: i32, mtime: i32) { |
|
298 | 295 | self.flags.insert(Flags::WDIR_TRACKED | Flags::P1_TRACKED); |
|
299 | self.flags.remove( | |
|
300 | Flags::P2_TRACKED // This might be wrong | |
|
301 | | Flags::MERGED | |
|
302 | | Flags::CLEAN_P2 | |
|
303 | | Flags::POSSIBLY_DIRTY, | |
|
304 | ); | |
|
305 | self.mode = mode; | |
|
306 | self.size = size; | |
|
307 | self.mtime = mtime; | |
|
296 | self.mode_size = Some((mode, size)); | |
|
297 | self.mtime = Some(mtime); | |
|
308 | 298 | } |
|
309 | 299 | |
|
310 | 300 | pub fn set_tracked(&mut self) { |
|
311 | self.flags | |
|
312 | .insert(Flags::WDIR_TRACKED | Flags::POSSIBLY_DIRTY); | |
|
313 | // size = None on the python size turn into size = NON_NORMAL when | |
|
314 | // accessed. So the next line is currently required, but a some future | |
|
315 | // clean up would be welcome. | |
|
316 | self.size = SIZE_NON_NORMAL; | |
|
301 | self.flags.insert(Flags::WDIR_TRACKED); | |
|
302 | // `set_tracked` is replacing various `normallookup` call. So we mark | |
|
303 | // the files as needing lookup | |
|
304 | // | |
|
305 | // Consider dropping this in the future in favor of something less | |
|
306 | // broad. | |
|
307 | self.mtime = None; | |
|
317 | 308 | } |
|
318 | 309 | |
|
319 | 310 | pub fn set_untracked(&mut self) { |
|
320 | 311 | self.flags.remove(Flags::WDIR_TRACKED); |
|
321 |
self.mode = |
|
|
322 |
self. |
|
|
323 | self.mtime = 0; | |
|
312 | self.mode_size = None; | |
|
313 | self.mtime = None; | |
|
324 | 314 | } |
|
325 | 315 | |
|
326 | 316 | /// Returns `(state, mode, size, mtime)` for the puprose of serialization |
@@ -330,7 +320,12 b' impl DirstateEntry {' | |||
|
330 | 320 | /// want to not represent these cases that way in memory, but serialization |
|
331 | 321 | /// will need to keep the same format. |
|
332 | 322 | pub fn v1_data(&self) -> (u8, i32, i32, i32) { |
|
333 | (self.state().into(), self.mode(), self.size(), self.mtime()) | |
|
323 | ( | |
|
324 | self.v1_state().into(), | |
|
325 | self.v1_mode(), | |
|
326 | self.v1_size(), | |
|
327 | self.v1_mtime(), | |
|
328 | ) | |
|
334 | 329 | } |
|
335 | 330 | |
|
336 | 331 | pub(crate) fn is_from_other_parent(&self) -> bool { |
@@ -354,12 +349,7 b' impl DirstateEntry {' | |||
|
354 | 349 | /// Returns a `(state, mode, size, mtime)` tuple as for |
|
355 | 350 | /// `DirstateMapMethods::debug_iter`. |
|
356 | 351 | pub fn debug_tuple(&self) -> (u8, i32, i32, i32) { |
|
357 | let state = if self.flags.contains(Flags::ENTRYLESS_TREE_NODE) { | |
|
358 | b' ' | |
|
359 | } else { | |
|
360 | self.state().into() | |
|
361 | }; | |
|
362 | (state, self.mode(), self.size(), self.mtime()) | |
|
352 | (self.state().into(), self.mode(), self.size(), self.mtime()) | |
|
363 | 353 | } |
|
364 | 354 | |
|
365 | 355 | pub fn mtime_is_ambiguous(&self, now: i32) -> bool { |
@@ -378,14 +368,10 b' impl DirstateEntry {' | |||
|
378 | 368 | // dirstate, forcing future 'status' calls to compare the |
|
379 | 369 | // contents of the file if the size is the same. This prevents |
|
380 | 370 | // mistakenly treating such files as clean. |
|
381 |
self. |
|
|
371 | self.set_possibly_dirty() | |
|
382 | 372 | } |
|
383 | 373 | ambiguous |
|
384 | 374 | } |
|
385 | ||
|
386 | pub fn clear_mtime(&mut self) { | |
|
387 | self.mtime = -1; | |
|
388 | } | |
|
389 | 375 | } |
|
390 | 376 | |
|
391 | 377 | impl EntryState { |
@@ -695,7 +695,7 b" impl<'on_disk> DirstateMap<'on_disk> {" | |||
|
695 | 695 | path.as_ref(), |
|
696 | 696 | )? { |
|
697 | 697 | if let NodeData::Entry(entry) = &mut node.data { |
|
698 |
entry. |
|
|
698 | entry.set_possibly_dirty(); | |
|
699 | 699 | } |
|
700 | 700 | } |
|
701 | 701 | } |
@@ -6,7 +6,6 b' use cpython::PyObject;' | |||
|
6 | 6 | use cpython::PyResult; |
|
7 | 7 | use cpython::Python; |
|
8 | 8 | use cpython::PythonObject; |
|
9 | use hg::dirstate::entry::Flags; | |
|
10 | 9 | use hg::dirstate::DirstateEntry; |
|
11 | 10 | use hg::dirstate::EntryState; |
|
12 | 11 | use std::cell::Cell; |
@@ -19,23 +18,25 b' py_class!(pub class DirstateItem |py| {' | |||
|
19 | 18 | _cls, |
|
20 | 19 | wc_tracked: bool = false, |
|
21 | 20 | p1_tracked: bool = false, |
|
22 |
p2_ |
|
|
23 |
|
|
|
24 |
|
|
|
25 | clean_p2: bool = false, | |
|
26 | possibly_dirty: bool = false, | |
|
21 | p2_info: bool = false, | |
|
22 | has_meaningful_data: bool = true, | |
|
23 | has_meaningful_mtime: bool = true, | |
|
27 | 24 | parentfiledata: Option<(i32, i32, i32)> = None, |
|
28 | 25 | |
|
29 | 26 | ) -> PyResult<DirstateItem> { |
|
30 | let mut flags = Flags::empty(); | |
|
31 | flags.set(Flags::WDIR_TRACKED, wc_tracked); | |
|
32 | flags.set(Flags::P1_TRACKED, p1_tracked); | |
|
33 | flags.set(Flags::P2_TRACKED, p2_tracked); | |
|
34 | flags.set(Flags::MERGED, merged); | |
|
35 | flags.set(Flags::CLEAN_P1, clean_p1); | |
|
36 | flags.set(Flags::CLEAN_P2, clean_p2); | |
|
37 | flags.set(Flags::POSSIBLY_DIRTY, possibly_dirty); | |
|
38 | let entry = DirstateEntry::new(flags, parentfiledata); | |
|
27 | let mut mode_size_opt = None; | |
|
28 | let mut mtime_opt = None; | |
|
29 | if let Some((mode, size, mtime)) = parentfiledata { | |
|
30 | if has_meaningful_data { | |
|
31 | mode_size_opt = Some((mode, size)) | |
|
32 | } | |
|
33 | if has_meaningful_mtime { | |
|
34 | mtime_opt = Some(mtime) | |
|
35 | } | |
|
36 | } | |
|
37 | let entry = DirstateEntry::new( | |
|
38 | wc_tracked, p1_tracked, p2_info, mode_size_opt, mtime_opt, | |
|
39 | ); | |
|
39 | 40 | DirstateItem::create_instance(py, Cell::new(entry)) |
|
40 | 41 | } |
|
41 | 42 |
General Comments 0
You need to be logged in to leave comments.
Login now