##// END OF EJS Templates
dirstate: factor the "changing" context logic out...
marmoute -
r50919:0dc2fb4b default
parent child Browse files
Show More
@@ -91,6 +91,9 b' def requires_not_changing_parents(func):'
91 91 return wrap
92 92
93 93
94 CHANGE_TYPE_PARENTS = "parents"
95
96
94 97 @interfaceutil.implementer(intdirstate.idirstate)
95 98 class dirstate:
96 99 def __init__(
@@ -129,6 +132,8 b' class dirstate:'
129 132 self._filecache = {}
130 133 # nesting level of `changing_parents` context
131 134 self._changing_level = 0
135 # the change currently underway
136 self._change_type = None
132 137 # True if the current dirstate changing operations have been
133 138 # invalidated (used to make sure all nested contexts have been exited)
134 139 self._invalidated_context = False
@@ -151,19 +156,25 b' class dirstate:'
151 156 self._pl
152 157
153 158 @contextlib.contextmanager
154 def changing_parents(self, repo):
155 """Context manager for handling dirstate parents.
156
157 If an exception occurs in the scope of the context manager,
158 the incoherent dirstate won't be written when wlock is
159 released.
160 """
159 def _changing(self, repo, change_type):
161 160 if repo.currentwlock() is None:
162 msg = b"changing parents without holding the wlock"
161 msg = b"trying to change the dirstate without holding the wlock"
163 162 raise error.ProgrammingError(msg)
164 163 if self._invalidated_context:
165 164 msg = "trying to use an invalidated dirstate before it has reset"
166 165 raise error.ProgrammingError(msg)
166
167 # different type of change are mutually exclusive
168 if self._change_type is None:
169 assert self._changing_level == 0
170 self._change_type = change_type
171 elif self._change_type != change_type:
172 msg = (
173 'trying to open "%s" dirstate-changing context while a "%s" is'
174 ' already open'
175 )
176 msg %= (change_type, self._change_type)
177 raise error.ProgrammingError(msg)
167 178 self._changing_level += 1
168 179 try:
169 180 yield
@@ -180,6 +191,7 b' class dirstate:'
180 191 # The invalidation is complete once we exit the final context
181 192 # manager
182 193 if self._changing_level <= 0:
194 self._change_type = None
183 195 assert self._changing_level == 0
184 196 if self._invalidated_context:
185 197 self._invalidated_context = False
@@ -194,6 +206,11 b' class dirstate:'
194 206 # instead of the top level one.
195 207 self.write(repo.currenttransaction())
196 208
209 @contextlib.contextmanager
210 def changing_parents(self, repo):
211 with self._changing(repo, CHANGE_TYPE_PARENTS) as c:
212 yield c
213
197 214 # here to help migration to the new code
198 215 def parentchange(self):
199 216 msg = (
@@ -211,6 +228,9 b' class dirstate:'
211 228 return self._changing_level > 0
212 229
213 230 def pendingparentchange(self):
231 return self.is_changing_parent()
232
233 def is_changing_parent(self):
214 234 """Returns true if the dirstate is in the middle of a set of changes
215 235 that modify the dirstate parent.
216 236 """
@@ -222,7 +242,9 b' class dirstate:'
222 242 """Returns true if the dirstate is in the middle of a set of changes
223 243 that modify the dirstate parent.
224 244 """
225 return self._changing_level > 0
245 if self._changing_level <= 0:
246 return False
247 return self._change_type == CHANGE_TYPE_PARENTS
226 248
227 249 @propertycache
228 250 def _map(self):
General Comments 0
You need to be logged in to leave comments. Login now