sparse: fix multiple wrapping of dirstate

Summary:
The dirstate wrapping functions were being run as part of reposetup, which
caused them to be wrapped multiple times, resulting in it exceeding the stack
size in some cases.

This moves the dirstate wrapping to be at extsetup time.

Test Plan:
histedit in facebook-hg-rpms used to break with stack overflow
errors. Now it doesn't. It seems the issues is more likely in repos with lots of
subrepos.

Reviewers: rmcelroy, ericsumner, lcharignon, pyd

Differential Revision: https://phabricator.fb.com/D2152047
This commit is contained in:
Durham Goode 2015-06-12 12:45:14 -07:00
parent 8dbd058742
commit 97e498b39a

View File

@ -9,6 +9,7 @@
"""
from mercurial import util, cmdutil, extensions, context, dirstate, commands
from mercurial import localrepo
from mercurial import match as matchmod
from mercurial import merge as mergemod
from mercurial.node import nullid
@ -26,6 +27,7 @@ def uisetup(ui):
def extsetup(ui):
_setuplog(ui)
_setupadd(ui)
_setupdirstate(ui)
# if hgwatchman is installed, tell it to use our hash function
try:
hgwatchman = extensions.find('hgwatchman')
@ -39,7 +41,6 @@ def reposetup(ui, repo):
if not util.safehasattr(repo, 'dirstate'):
return
_setupdirstate(ui, repo)
_wraprepo(ui, repo)
def wrapfilecache(cls, propname, wrapper):
@ -226,7 +227,7 @@ def _setupadd(ui):
extensions.wrapcommand(commands.table, 'add', _add)
def _setupdirstate(ui, repo):
def _setupdirstate(ui):
"""Modify the dirstate to prevent stat'ing excluded files,
and to prevent modifications to files outside the checkout.
"""
@ -235,9 +236,7 @@ def _setupdirstate(ui, repo):
dirstate = orig(repo)
dirstate.repo = repo
return dirstate
wrapfilecache(repo.__class__, 'dirstate', _dirstate)
if 'dirstate' in repo._filecache:
repo.dirstate.repo = repo
wrapfilecache(localrepo.localrepository, 'dirstate', _dirstate)
# The atrocity below is needed to wrap dirstate._ignore. It is a cached
# property, which means normal function wrapping doesn't work.
@ -498,6 +497,9 @@ def _wraprepo(ui, repo):
ui.status("cleaned up %d temporarily added file(s) from the sparse checkout\n" %
len(tempincludes))
if 'dirstate' in repo._filecache:
repo.dirstate.repo = repo
repo.sparsecache = {}
repo.__class__ = SparseRepo