localrepo: enforce a clean dirstate when the transaction open
This is important to simplify the backup process. This also seems like a quite
reasonable expectation. See inline documentation for details.
--- a/mercurial/localrepo.py Thu Feb 16 10:43:22 2023 +0100
+++ b/mercurial/localrepo.py Thu Feb 16 04:04:40 2023 +0100
@@ -2375,6 +2375,21 @@
hint=_(b"run 'hg recover' to clean up transaction"),
)
+ # At that point your dirstate should be clean:
+ #
+ # - If you don't have the wlock, why would you still have a dirty
+ # dirstate ?
+ #
+ # - If you hold the wlock, you should not be opening a transaction in
+ # the middle of a `distate.changing_*` block. The transaction needs to
+ # be open before that and wrap the change-context.
+ #
+ # - If you are not within a `dirstate.changing_*` context, why is our
+ # dirstate dirty?
+ if self.dirstate._dirty:
+ m = "cannot open a transaction with a dirty dirstate"
+ raise error.ProgrammingError(m)
+
idbase = b"%.40f#%f" % (random.random(), time.time())
ha = hex(hashutil.sha1(idbase).digest())
txnid = b'TXN:' + ha