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