D6664: transaction: leave unfinished without crashing when not properly released

martinvonz (Martin von Zweigbergk) phabricator at mercurial-scm.org
Sun Jul 21 11:01:23 EDT 2019


martinvonz created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  I think the transaction.__del__ is there just as a last resort in case
  we (or an extension) forgot to release the transaction. When that
  happens, the repo can (or will on Python 3?) get deleted before the
  transaction. This leads to a crash in test-devel-warnings.t on Python
  3 because we tried to access repo.dirstate, where repo was retried
  from a weak reference. There's not much we can do here, but let's at
  least avoid the crash. The user will have run `hg recover` afterwards
  regardless.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D6664

AFFECTED FILES
  mercurial/localrepo.py

CHANGE DETAILS

diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1893,6 +1893,12 @@
                       **pycompat.strkwargs(tr.hookargs))
         def releasefn(tr, success):
             repo = reporef()
+            if repo is None:
+                # If the repo has been GC'd (and this release function is being
+                # called from transaction.__del__), there's not much we can do,
+                # so just leave the unfinished transaction there and let the
+                # user run `hg recover`.
+                return
             if success:
                 # this should be explicitly invoked here, because
                 # in-memory changes aren't written out at closing



To: martinvonz, #hg-reviewers
Cc: mercurial-devel


More information about the Mercurial-devel mailing list