##// END OF EJS Templates
dirstate-item: keep the full information in memory (for pure form)...
marmoute -
r48739:b81f52ca default
parent child Browse files
Show More
@@ -56,7 +56,17 b' class DirstateItem(object):'
56 - mtime,
56 - mtime,
57 """
57 """
58
58
59 _state = attr.ib()
59 _wc_tracked = attr.ib()
60 _p1_tracked = attr.ib()
61 _p2_tracked = attr.ib()
62 # the three item above should probably be combined
63 #
64 # However it is unclear if they properly cover some of the most advanced
65 # merge case. So we should probably wait on this to be settled.
66 _merged = attr.ib()
67 _clean_p1 = attr.ib()
68 _clean_p2 = attr.ib()
69 _possibly_dirty = attr.ib()
60 _mode = attr.ib()
70 _mode = attr.ib()
61 _size = attr.ib()
71 _size = attr.ib()
62 _mtime = attr.ib()
72 _mtime = attr.ib()
@@ -76,47 +86,21 b' class DirstateItem(object):'
76 msg = b'`merged` argument incompatible with `clean_p1`/`clean_p2`'
86 msg = b'`merged` argument incompatible with `clean_p1`/`clean_p2`'
77 raise error.ProgrammingError(msg)
87 raise error.ProgrammingError(msg)
78
88
79 self._state = None
89 self._wc_tracked = wc_tracked
80 self._mode = 0
90 self._p1_tracked = p1_tracked
81 self._size = NONNORMAL
91 self._p2_tracked = p2_tracked
82 self._mtime = AMBIGUOUS_TIME
92 self._merged = merged
83 if not (p1_tracked or p2_tracked or wc_tracked):
93 self._clean_p1 = clean_p1
84 pass # the object has no state to record
94 self._clean_p2 = clean_p2
85 elif merged:
95 self._possibly_dirty = possibly_dirty
86 self._state = b'm'
87 self._size = FROM_P2
88 self._mtime = AMBIGUOUS_TIME
89 elif not (p1_tracked or p2_tracked) and wc_tracked:
90 self._state = b'a'
91 self._size = NONNORMAL
92 self._mtime = AMBIGUOUS_TIME
93 elif (p1_tracked or p2_tracked) and not wc_tracked:
94 self._state = b'r'
95 self._size = 0
96 self._mtime = 0
97 elif clean_p2 and wc_tracked:
98 self._state = b'n'
99 self._size = FROM_P2
100 self._mtime = AMBIGUOUS_TIME
101 elif not p1_tracked and p2_tracked and wc_tracked:
102 self._state = b'n'
103 self._size = FROM_P2
104 self._mtime = AMBIGUOUS_TIME
105 elif possibly_dirty:
106 self._state = b'n'
107 self._size = NONNORMAL
108 self._mtime = AMBIGUOUS_TIME
109 elif wc_tracked:
110 # this is a "normal" file
111 if parentfiledata is None:
96 if parentfiledata is None:
112 msg = b'failed to pass parentfiledata for a normal file'
97 self._mode = None
113 raise error.ProgrammingError(msg)
98 self._size = None
114 self._state = b'n'
99 self._mtime = None
100 else:
115 self._mode = parentfiledata[0]
101 self._mode = parentfiledata[0]
116 self._size = parentfiledata[1]
102 self._size = parentfiledata[1]
117 self._mtime = parentfiledata[2]
103 self._mtime = parentfiledata[2]
118 else:
119 assert False, 'unreachable'
120
104
121 @classmethod
105 @classmethod
122 def new_added(cls):
106 def new_added(cls):
@@ -125,10 +109,9 b' class DirstateItem(object):'
125 Should eventually be removed
109 Should eventually be removed
126 """
110 """
127 instance = cls()
111 instance = cls()
128 instance._state = b'a'
112 instance._wc_tracked = True
129 instance._mode = 0
113 instance._p1_tracked = False
130 instance._size = NONNORMAL
114 instance._p2_tracked = False
131 instance._mtime = AMBIGUOUS_TIME
132 return instance
115 return instance
133
116
134 @classmethod
117 @classmethod
@@ -138,10 +121,10 b' class DirstateItem(object):'
138 Should eventually be removed
121 Should eventually be removed
139 """
122 """
140 instance = cls()
123 instance = cls()
141 instance._state = b'm'
124 instance._wc_tracked = True
142 instance._mode = 0
125 instance._p1_tracked = True # might not be True because of rename ?
143 instance._size = FROM_P2
126 instance._p2_tracked = True # might not be True because of rename ?
144 instance._mtime = AMBIGUOUS_TIME
127 instance._merged = True
145 return instance
128 return instance
146
129
147 @classmethod
130 @classmethod
@@ -151,10 +134,10 b' class DirstateItem(object):'
151 Should eventually be removed
134 Should eventually be removed
152 """
135 """
153 instance = cls()
136 instance = cls()
154 instance._state = b'n'
137 instance._wc_tracked = True
155 instance._mode = 0
138 instance._p1_tracked = False # might actually be True
156 instance._size = FROM_P2
139 instance._p2_tracked = True
157 instance._mtime = AMBIGUOUS_TIME
140 instance._clean_p2 = True
158 return instance
141 return instance
159
142
160 @classmethod
143 @classmethod
@@ -164,10 +147,9 b' class DirstateItem(object):'
164 Should eventually be removed
147 Should eventually be removed
165 """
148 """
166 instance = cls()
149 instance = cls()
167 instance._state = b'n'
150 instance._wc_tracked = True
168 instance._mode = 0
151 instance._p1_tracked = True
169 instance._size = NONNORMAL
152 instance._possibly_dirty = True
170 instance._mtime = AMBIGUOUS_TIME
171 return instance
153 return instance
172
154
173 @classmethod
155 @classmethod
@@ -179,7 +161,8 b' class DirstateItem(object):'
179 assert size != FROM_P2
161 assert size != FROM_P2
180 assert size != NONNORMAL
162 assert size != NONNORMAL
181 instance = cls()
163 instance = cls()
182 instance._state = b'n'
164 instance._wc_tracked = True
165 instance._p1_tracked = True
183 instance._mode = mode
166 instance._mode = mode
184 instance._size = size
167 instance._size = size
185 instance._mtime = mtime
168 instance._mtime = mtime
@@ -192,12 +175,44 b' class DirstateItem(object):'
192 Since the dirstate-v1 format is frozen, the signature of this function
175 Since the dirstate-v1 format is frozen, the signature of this function
193 is not expected to change, unlike the __init__ one.
176 is not expected to change, unlike the __init__ one.
194 """
177 """
178 if state == b'm':
179 return cls.new_merged()
180 elif state == b'a':
181 return cls.new_added()
182 elif state == b'r':
195 instance = cls()
183 instance = cls()
196 instance._state = state
184 instance._wc_tracked = False
197 instance._mode = mode
185 if size == NONNORMAL:
198 instance._size = size
186 instance._merged = True
199 instance._mtime = mtime
187 instance._p1_tracked = (
188 True # might not be True because of rename ?
189 )
190 instance._p2_tracked = (
191 True # might not be True because of rename ?
192 )
193 elif size == FROM_P2:
194 instance._clean_p2 = True
195 instance._p1_tracked = (
196 False # We actually don't know (file history)
197 )
198 instance._p2_tracked = True
199 else:
200 instance._p1_tracked = True
200 return instance
201 return instance
202 elif state == b'n':
203 if size == FROM_P2:
204 return cls.new_from_p2()
205 elif size == NONNORMAL:
206 return cls.new_possibly_dirty()
207 elif mtime == AMBIGUOUS_TIME:
208 instance = cls.new_normal(mode, size, 42)
209 instance._mtime = None
210 instance._possibly_dirty = True
211 return instance
212 else:
213 return cls.new_normal(mode, size, mtime)
214 else:
215 raise RuntimeError(b'unknown state: %s' % state)
201
216
202 def set_possibly_dirty(self):
217 def set_possibly_dirty(self):
203 """Mark a file as "possibly dirty"
218 """Mark a file as "possibly dirty"
@@ -205,7 +220,7 b' class DirstateItem(object):'
205 This means the next status call will have to actually check its content
220 This means the next status call will have to actually check its content
206 to make sure it is correct.
221 to make sure it is correct.
207 """
222 """
208 self._mtime = AMBIGUOUS_TIME
223 self._possibly_dirty = True
209
224
210 def set_untracked(self):
225 def set_untracked(self):
211 """mark a file as untracked in the working copy
226 """mark a file as untracked in the working copy
@@ -213,15 +228,10 b' class DirstateItem(object):'
213 This will ultimately be called by command like `hg remove`.
228 This will ultimately be called by command like `hg remove`.
214 """
229 """
215 # backup the previous state (useful for merge)
230 # backup the previous state (useful for merge)
216 size = 0
231 self._wc_tracked = False
217 if self.merged: # merge
232 self._mode = None
218 size = NONNORMAL
233 self._size = None
219 elif self.from_p2:
234 self._mtime = None
220 size = FROM_P2
221 self._state = b'r'
222 self._mode = 0
223 self._size = size
224 self._mtime = 0
225
235
226 @property
236 @property
227 def mode(self):
237 def mode(self):
@@ -319,19 +329,89 b' class DirstateItem(object):'
319
329
320 def v1_state(self):
330 def v1_state(self):
321 """return a "state" suitable for v1 serialization"""
331 """return a "state" suitable for v1 serialization"""
322 return self._state
332 if not (self._p1_tracked or self._p2_tracked or self._wc_tracked):
333 # the object has no state to record, this is -currently-
334 # unsupported
335 raise RuntimeError('untracked item')
336 elif not self._wc_tracked:
337 return b'r'
338 elif self._merged:
339 return b'm'
340 elif not (self._p1_tracked or self._p2_tracked) and self._wc_tracked:
341 return b'a'
342 elif self._clean_p2 and self._wc_tracked:
343 return b'n'
344 elif not self._p1_tracked and self._p2_tracked and self._wc_tracked:
345 return b'n'
346 elif self._possibly_dirty:
347 return b'n'
348 elif self._wc_tracked:
349 return b'n'
350 else:
351 raise RuntimeError('unreachable')
323
352
324 def v1_mode(self):
353 def v1_mode(self):
325 """return a "mode" suitable for v1 serialization"""
354 """return a "mode" suitable for v1 serialization"""
326 return self._mode
355 return self._mode if self._mode is not None else 0
327
356
328 def v1_size(self):
357 def v1_size(self):
329 """return a "size" suitable for v1 serialization"""
358 """return a "size" suitable for v1 serialization"""
359 if not (self._p1_tracked or self._p2_tracked or self._wc_tracked):
360 # the object has no state to record, this is -currently-
361 # unsupported
362 raise RuntimeError('untracked item')
363 elif not self._wc_tracked:
364 # File was deleted
365 if self._merged:
366 return NONNORMAL
367 elif self._clean_p2:
368 return FROM_P2
369 else:
370 return 0
371 elif self._merged:
372 return FROM_P2
373 elif not (self._p1_tracked or self._p2_tracked) and self._wc_tracked:
374 # Added
375 return NONNORMAL
376 elif self._clean_p2 and self._wc_tracked:
377 return FROM_P2
378 elif not self._p1_tracked and self._p2_tracked and self._wc_tracked:
379 return FROM_P2
380 elif self._possibly_dirty:
381 if self._size is None:
382 return NONNORMAL
383 else:
330 return self._size
384 return self._size
385 elif self._wc_tracked:
386 return self._size
387 else:
388 raise RuntimeError('unreachable')
331
389
332 def v1_mtime(self):
390 def v1_mtime(self):
333 """return a "mtime" suitable for v1 serialization"""
391 """return a "mtime" suitable for v1 serialization"""
392 if not (self._p1_tracked or self._p2_tracked or self._wc_tracked):
393 # the object has no state to record, this is -currently-
394 # unsupported
395 raise RuntimeError('untracked item')
396 elif not self._wc_tracked:
397 return 0
398 elif self._possibly_dirty:
399 return AMBIGUOUS_TIME
400 elif self._merged:
401 return AMBIGUOUS_TIME
402 elif not (self._p1_tracked or self._p2_tracked) and self._wc_tracked:
403 return AMBIGUOUS_TIME
404 elif self._clean_p2 and self._wc_tracked:
405 return AMBIGUOUS_TIME
406 elif not self._p1_tracked and self._p2_tracked and self._wc_tracked:
407 return AMBIGUOUS_TIME
408 elif self._wc_tracked:
409 if self._mtime is None:
410 return 0
411 else:
334 return self._mtime
412 return self._mtime
413 else:
414 raise RuntimeError('unreachable')
335
415
336 def need_delay(self, now):
416 def need_delay(self, now):
337 """True if the stored mtime would be ambiguous with the current time"""
417 """True if the stored mtime would be ambiguous with the current time"""
General Comments 0
You need to be logged in to leave comments. Login now