[PATCH] tr-summary: keep a weakref to the unfiltered repository
boris.feld at octobus.net
Sat Nov 25 16:35:51 EST 2017
# HG changeset patch
# User Boris Feld <boris.feld at octobus.net>
# Date 1511578301 18000
# Fri Nov 24 21:51:41 2017 -0500
# Branch stable
# Node ID a2eccde70ce65f9f0e8735e1bc8d51f58c8cdd71
# Parent 02845f7441aff30bc01975a5881cabfa922c12d4
# EXP-Topic callback-error
# Available At https://bitbucket.org/octobus/mercurial-devel/
# hg pull https://bitbucket.org/octobus/mercurial-devel/ -r a2eccde70ce6
tr-summary: keep a weakref to the unfiltered repository
Repoview can have a different life cycle, causing issue in some corner
cases. The particular instance that revealed this comes from localpeer. The
localpeer hold a reference to the unfiltered repository, but calling 'local()'
will create an on-demand 'visible' repoview. That repoview can be garbaged
collected any time. Here is a simplified step by step reproduction::
1) tr = peer.local().transaction('foo')
After (1), the repoview object is garbage collected, so weakref used in (2)
point to nothing.
Thanks to Sean Farley for helping raising and debugging this issue.
diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
@@ -1233,9 +1233,17 @@ def registersummarycallback(repo, otr, t
"""decorator for report callbacks."""
- reporef = weakref.ref(repo)
+ # The repoview life cycle is shorter than the one of the actual
+ # underlying repository. So the filtered object can die before the
+ # weakref is used leading to troubles. We keep a reference to the
+ # unfiltered object and restore the filtering when retrieving the
+ # repository through the weakref.
+ filtername = repo.filtername
+ reporef = weakref.ref(repo.unfiltered())
repo = reporef()
+ if filtername:
+ repo = repo.filtered(filtername)
newcat = '%2i-txnreport' % len(categories)
More information about the Mercurial-devel