Mercurial > hg
changeset 50120:a7d11833ff48
dirstate: simplify the invalidation management on context exit
Since the `invalidate` call will directly reset the `_invalidated_context` attribut, we can simplify the code.
In the same go, we move most of the logic out of the `finally` clause. It seems
cleaner and safer. If we are handling an exception, we don't need the `write`
code anyway.
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Mon, 20 Feb 2023 15:58:17 +0100 |
parents | de42ba9dd852 |
children | 15531d101313 |
files | mercurial/dirstate.py |
diffstat | 1 files changed, 26 insertions(+), 31 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/dirstate.py Mon Feb 20 15:52:55 2023 +0100 +++ b/mercurial/dirstate.py Mon Feb 20 15:58:17 2023 +0100 @@ -204,6 +204,7 @@ msg = "entering a changing context, but dirstate is already dirty" raise error.ProgrammingError(msg) + assert self._changing_level >= 0 # different type of change are mutually exclusive if self._change_type is None: assert self._changing_level == 0 @@ -215,43 +216,37 @@ ) msg %= (change_type, self._change_type) raise error.ProgrammingError(msg) + should_write = False self._changing_level += 1 try: yield except: # re-raises - self.invalidate() + self.invalidate() # this will set `_invalidated_context` raise finally: - tr = repo.currenttransaction() - if self._changing_level > 0: - if self._invalidated_context: - # make sure we invalidate anything an upper context might - # have changed. - self.invalidate() - self._changing_level -= 1 - # The invalidation is complete once we exit the final context - # manager - if self._changing_level <= 0: - self._change_type = None - assert self._changing_level == 0 - if self._invalidated_context: - self._invalidated_context = False - else: - # When an exception occured, `_invalidated_context` - # would have been set to True by the `invalidate` - # call earlier. - # - # We don't have more straightforward code, because the - # Exception catching (and the associated `invalidate` - # calling) might have been called by a nested context - # instead of the top level one. - self.write(tr) - if has_tr != (tr is not None): - if has_tr: - m = "transaction vanished while changing dirstate" - else: - m = "transaction appeared while changing dirstate" - raise error.ProgrammingError(m) + assert self._changing_level > 0 + self._changing_level -= 1 + # If the dirstate is being invalidated, call invalidate again. + # This will throw away anything added by a upper context and + # reset the `_invalidated_context` flag when relevant + if self._changing_level <= 0: + self._change_type = None + assert self._changing_level == 0 + if self._invalidated_context: + # make sure we invalidate anything an upper context might + # have changed. + self.invalidate() + else: + should_write = self._changing_level <= 0 + tr = repo.currenttransaction() + if has_tr != (tr is not None): + if has_tr: + m = "transaction vanished while changing dirstate" + else: + m = "transaction appeared while changing dirstate" + raise error.ProgrammingError(m) + if should_write: + self.write(tr) @contextlib.contextmanager def changing_parents(self, repo):