# HG changeset patch # User Pierre-Yves David # Date 2022-06-10 22:56:50 # Node ID 0540c1628fd45bedc504696b266229fcec7e6333 # Parent 216f273b6b30a66a64a972fa451e80bf4d43f33f sparse: use None as the sparse matcher value when disabled This create a clear signal for when the feature is unused. We could also create an `alwaysmatcher`, but using None is more explicit, so I went for it. diff --git a/hgext/sparse.py b/hgext/sparse.py --- a/hgext/sparse.py +++ b/hgext/sparse.py @@ -216,9 +216,11 @@ def _setupdirstate(ui): def walk(orig, self, match, subrepos, unknown, ignored, full=True): # hack to not exclude explicitly-specified paths so that they can # be warned later on e.g. dirstate.add() - em = matchmod.exact(match.files()) - sm = matchmod.unionmatcher([self._sparsematcher, em]) - match = matchmod.intersectmatchers(match, sm) + sparse_matcher = self._sparsematcher + if sparse_matcher is not None: + em = matchmod.exact(match.files()) + sm = matchmod.unionmatcher([self._sparsematcher, em]) + match = matchmod.intersectmatchers(match, sm) return orig(self, match, subrepos, unknown, ignored, full) extensions.wrapfunction(dirstate.dirstate, b'walk', walk) @@ -226,7 +228,7 @@ def _setupdirstate(ui): # dirstate.rebuild should not add non-matching files def _rebuild(orig, self, parent, allfiles, changedfiles=None): matcher = self._sparsematcher - if not matcher.always(): + if matcher is not None and not matcher.always(): allfiles = [f for f in allfiles if matcher(f)] if changedfiles: changedfiles = [f for f in changedfiles if matcher(f)] @@ -255,7 +257,7 @@ def _setupdirstate(ui): def _wrapper(orig, self, *args, **kwargs): sparsematch = self._sparsematcher - if not sparsematch.always(): + if sparsematch is not None and not sparsematch.always(): for f in args: if f is not None and not sparsematch(f) and f not in self: raise error.Abort( diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py --- a/mercurial/dirstate.py +++ b/mercurial/dirstate.py @@ -27,7 +27,6 @@ from . import ( policy, pycompat, scmutil, - sparse, util, ) @@ -113,6 +112,7 @@ class dirstate: self._opener = opener self._validate = validate self._root = root + # Either build a sparse-matcher or None if sparse is disabled 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) @@ -184,7 +184,11 @@ class dirstate: 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. + + When sparse if disabled, return None. """ + if self._sparsematchfn is None: + return None # 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.) @@ -1259,7 +1263,7 @@ class dirstate: use_rust = False elif subrepos: use_rust = False - elif sparse.enabled: + elif self._sparsematchfn is not None: use_rust = False elif not isinstance(match, allowed_matchers): # Some matchers have yet to be implemented diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -1747,7 +1747,9 @@ class localrepository: def _makedirstate(self): """Extension point for wrapping the dirstate per-repo.""" - sparsematchfn = lambda: sparse.matcher(self) + sparsematchfn = None + if sparse.use_sparse(self): + sparsematchfn = lambda: sparse.matcher(self) v2_req = requirementsmod.DIRSTATE_V2_REQUIREMENT th = requirementsmod.DIRSTATE_TRACKED_HINT_V1 use_dirstate_v2 = v2_req in self.requirements