@@ -26,6 +26,7 @@ from mercurial import (
node,
pycompat,
scmutil,
+ sparse,
util,
vfs as vfsmod,
)
@@ -147,7 +148,8 @@ def openlfdirstate(ui, repo, create=True
lfstoredir = longname
opener = vfsmod.vfs(vfs.join(lfstoredir))
lfdirstate = largefilesdirstate(opener, ui, repo.root,
- repo.dirstate._validate)
+ repo.dirstate._validate,
+ lambda: sparse.matcher(repo))
# If the largefiles dirstate does not exist, populate and create
# it. This ensures that we create it on the first meaningful
@@ -82,7 +82,6 @@ from mercurial import (
error,
extensions,
hg,
- localrepo,
match as matchmod,
registrar,
sparse,
@@ -106,13 +105,6 @@ def extsetup(ui):
_setupadd(ui)
_setupdirstate(ui)
-def reposetup(ui, repo):
- if not util.safehasattr(repo, 'dirstate'):
- return
-
- if 'dirstate' in repo._filecache:
- repo.dirstate.repo = repo
-
def replacefilecache(cls, propname, replacement):
"""Replace a filecache property with a new class. This allows changing the
cache invalidation condition."""
@@ -200,13 +192,6 @@ def _setupdirstate(ui):
and to prevent modifications to files outside the checkout.
"""
- def _dirstate(orig, repo):
- dirstate = orig(repo)
- dirstate.repo = repo
- return dirstate
- extensions.wrapfunction(
- localrepo.localrepository.dirstate, 'func', _dirstate)
-
# The atrocity below is needed to wrap dirstate._ignore. It is a cached
# property, which means normal function wrapping doesn't work.
class ignorewrapper(object):
@@ -217,10 +202,9 @@ def _setupdirstate(ui):
self.sparsematch = None
def __get__(self, obj, type=None):
- repo = obj.repo
origignore = self.orig.__get__(obj)
- sparsematch = sparse.matcher(repo)
+ sparsematch = obj._sparsematcher
if sparsematch.always():
return origignore
@@ -241,7 +225,7 @@ def _setupdirstate(ui):
# dirstate.rebuild should not add non-matching files
def _rebuild(orig, self, parent, allfiles, changedfiles=None):
- matcher = sparse.matcher(self.repo)
+ matcher = self._sparsematcher
if not matcher.always():
allfiles = allfiles.matches(matcher)
if changedfiles:
@@ -262,8 +246,7 @@ def _setupdirstate(ui):
'`hg add -s <file>` to include file directory while adding')
for func in editfuncs:
def _wrapper(orig, self, *args):
- repo = self.repo
- sparsematch = sparse.matcher(repo)
+ sparsematch = self._sparsematcher
if not sparsematch.always():
for f in args:
if (f is not None and not sparsematch(f) and
@@ -70,7 +70,7 @@ def nonnormalentries(dmap):
class dirstate(object):
- def __init__(self, opener, ui, root, validate):
+ def __init__(self, opener, ui, root, validate, sparsematchfn):
'''Create a new dirstate object.
opener is an open()-like callable that can be used to open the
@@ -80,6 +80,7 @@ class dirstate(object):
self._opener = opener
self._validate = validate
self._root = root
+ self._sparsematchfn = sparsematchfn
# ntpath.join(root, '') of Python 2.7.9 does not add sep if root is
# UNC path pointing to root share (issue4557)
self._rootdir = pathutil.normasprefix(root)
@@ -197,6 +198,19 @@ class dirstate(object):
f[normcase(name)] = name
return f
+ @property
+ def _sparsematcher(self):
+ """The matcher for the sparse checkout.
+
+ The working directory may not include every file from a manifest. The
+ matcher obtained by this property will match a path if it is to be
+ included in the working directory.
+ """
+ # TODO there is potential to cache this property. For now, the matcher
+ # is resolved on every access. (But the called function does use a
+ # cache to keep the lookup fast.)
+ return self._sparsematchfn()
+
@repocache('branch')
def _branch(self):
try:
@@ -53,6 +53,7 @@ from . import (
revset,
revsetlang,
scmutil,
+ sparse,
store,
subrepo,
tags as tagsmod,
@@ -570,8 +571,10 @@ class localrepository(object):
@repofilecache('dirstate')
def dirstate(self):
+ sparsematchfn = lambda: sparse.matcher(self)
+
return dirstate.dirstate(self.vfs, self.ui, self.root,
- self._dirstatevalidate)
+ self._dirstatevalidate, sparsematchfn)
def _dirstatevalidate(self, node):
try: