dirstate: detect potential fishy transaction patterns while changing
authorPierre-Yves David <pierre-yves.david@octobus.net>
Thu, 16 Feb 2023 02:44:07 +0100
changeset 50077 605f0ccffb43
parent 50076 63c4e9639753
child 50079 acd2a0267660
dirstate: detect potential fishy transaction patterns while changing If we rely on the transaction more, we should be more careful about the transaction. Adding extra security seems reasonable.
mercurial/dirstate.py
--- a/mercurial/dirstate.py	Thu Feb 16 02:34:54 2023 +0100
+++ b/mercurial/dirstate.py	Thu Feb 16 02:44:07 2023 +0100
@@ -176,6 +176,8 @@
             msg = "trying to use an invalidated dirstate before it has reset"
             raise error.ProgrammingError(msg)
 
+        has_tr = repo.currenttransaction() is not None
+
         # different type of change are mutually exclusive
         if self._change_type is None:
             assert self._changing_level == 0
@@ -194,6 +196,7 @@
             self.invalidate()
             raise
         finally:
+            tr = repo.currenttransaction()
             if self._changing_level > 0:
                 if self._invalidated_context:
                     # make sure we invalidate anything an upper context might
@@ -216,8 +219,13 @@
                         # Exception catching (and the associated `invalidate`
                         # calling) might have been called by a nested context
                         # instead of the top level one.
-                        tr = repo.currenttransaction()
                         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)
 
     @contextlib.contextmanager
     def changing_parents(self, repo):