Show More
@@ -72,6 +72,9 b' def requires_parents_change(func):' | |||||
72 | msg = 'calling `%s` outside of a parentchange context' |
|
72 | msg = 'calling `%s` outside of a parentchange context' | |
73 | msg %= func.__name__ |
|
73 | msg %= func.__name__ | |
74 | raise error.ProgrammingError(msg) |
|
74 | raise error.ProgrammingError(msg) | |
|
75 | if self._invalidated_context: | |||
|
76 | msg = 'calling `%s` after the dirstate was invalidated' | |||
|
77 | raise error.ProgrammingError(msg) | |||
75 | return func(self, *args, **kwargs) |
|
78 | return func(self, *args, **kwargs) | |
76 |
|
79 | |||
77 | return wrap |
|
80 | return wrap | |
@@ -124,7 +127,11 b' class dirstate:' | |||||
124 | self._dirty_tracked_set = False |
|
127 | self._dirty_tracked_set = False | |
125 | self._ui = ui |
|
128 | self._ui = ui | |
126 | self._filecache = {} |
|
129 | self._filecache = {} | |
|
130 | # nesting level of `parentchange` context | |||
127 | self._parentwriters = 0 |
|
131 | self._parentwriters = 0 | |
|
132 | # True if the current dirstate changing operations have been | |||
|
133 | # invalidated (used to make sure all nested contexts have been exited) | |||
|
134 | self._invalidated_context = False | |||
128 | self._filename = b'dirstate' |
|
135 | self._filename = b'dirstate' | |
129 | self._filename_th = b'dirstate-tracked-hint' |
|
136 | self._filename_th = b'dirstate-tracked-hint' | |
130 | self._pendingfilename = b'%s.pending' % self._filename |
|
137 | self._pendingfilename = b'%s.pending' % self._filename | |
@@ -151,14 +158,27 b' class dirstate:' | |||||
151 | the incoherent dirstate won't be written when wlock is |
|
158 | the incoherent dirstate won't be written when wlock is | |
152 | released. |
|
159 | released. | |
153 | """ |
|
160 | """ | |
|
161 | if self._invalidated_context: | |||
|
162 | msg = "trying to use an invalidated dirstate before it has reset" | |||
|
163 | raise error.ProgrammingError(msg) | |||
154 | self._parentwriters += 1 |
|
164 | self._parentwriters += 1 | |
155 |
|
|
165 | try: | |
156 | # Typically we want the "undo" step of a context manager in a |
|
166 | yield | |
157 | # finally block so it happens even when an exception |
|
167 | except Exception: | |
158 | # occurs. In this case, however, we only want to decrement |
|
168 | self.invalidate() | |
159 | # parentwriters if the code in the with statement exits |
|
169 | raise | |
160 | # normally, so we don't have a try/finally here on purpose. |
|
170 | finally: | |
161 |
self._parentwriters |
|
171 | if self._parentwriters > 0: | |
|
172 | if self._invalidated_context: | |||
|
173 | # make sure we invalidate anything an upper context might | |||
|
174 | # have changed. | |||
|
175 | self.invalidate() | |||
|
176 | self._parentwriters -= 1 | |||
|
177 | # The invalidation is complete once we exit the final context | |||
|
178 | # manager | |||
|
179 | if self._parentwriters <= 0: | |||
|
180 | assert self._parentwriters == 0 | |||
|
181 | self._invalidated_context = False | |||
162 |
|
182 | |||
163 | def pendingparentchange(self): |
|
183 | def pendingparentchange(self): | |
164 | """Returns true if the dirstate is in the middle of a set of changes |
|
184 | """Returns true if the dirstate is in the middle of a set of changes | |
@@ -419,7 +439,7 b' class dirstate:' | |||||
419 | delattr(self, a) |
|
439 | delattr(self, a) | |
420 | self._dirty = False |
|
440 | self._dirty = False | |
421 | self._dirty_tracked_set = False |
|
441 | self._dirty_tracked_set = False | |
422 |
self._ |
|
442 | self._invalidated_context = self._parentwriters > 0 | |
423 | self._origpl = None |
|
443 | self._origpl = None | |
424 |
|
444 | |||
425 | def copy(self, source, dest): |
|
445 | def copy(self, source, dest): |
General Comments 0
You need to be logged in to leave comments.
Login now