diff --git a/hgext/narrow/narrowcommands.py b/hgext/narrow/narrowcommands.py --- a/hgext/narrow/narrowcommands.py +++ b/hgext/narrow/narrowcommands.py @@ -31,6 +31,7 @@ wireprototypes, ) from mercurial.interfaces import repository +from mercurial.utils import dirstateutil table = {} command = registrar.command(table) @@ -277,7 +278,7 @@ todelete.append(f) elif f.startswith(b'meta/'): dir = f[5:-13] - dirs = sorted(util.dirs({dir})) + [dir] + dirs = sorted(dirstateutil.dirs({dir})) + [dir] include = True for d in dirs: visit = newmatch.visitdir(d) diff --git a/hgext/uncommit.py b/hgext/uncommit.py --- a/hgext/uncommit.py +++ b/hgext/uncommit.py @@ -33,8 +33,8 @@ registrar, rewriteutil, scmutil, - util, ) +from mercurial.utils import dirstateutil cmdtable = {} command = registrar.command(cmdtable) @@ -185,7 +185,7 @@ # if not everything tracked in that directory can be # uncommitted. if badfiles: - badfiles -= {f for f in util.dirs(eligible)} + badfiles -= {f for f in dirstateutil.dirs(eligible)} for f in sorted(badfiles): if f in s.clean: diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -58,6 +58,7 @@ from .utils import ( dateutil, + dirstateutil, stringutil, ) @@ -2606,7 +2607,7 @@ progress.complete() # warn about failure to delete explicit files/dirs - deleteddirs = util.dirs(deleted) + deleteddirs = dirstateutil.dirs(deleted) files = m.files() progress = ui.makeprogress( _(b'deleting'), total=len(files), unit=_(b'files') diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py --- a/mercurial/dirstate.py +++ b/mercurial/dirstate.py @@ -36,6 +36,8 @@ util as interfaceutil, ) +from .utils import dirstateutil + parsers = policy.importmod(r'parsers') rustmod = policy.importrust(r'dirstate') @@ -1504,11 +1506,11 @@ @propertycache def _dirs(self): - return util.dirs(self._map, b'r') + return dirstateutil.dirs(self._map, b'r') @propertycache def _alldirs(self): - return util.dirs(self._map) + return dirstateutil.dirs(self._map) def _opendirstatefile(self): fp, mode = txnutil.trypending(self._root, self._opener, self._filename) diff --git a/mercurial/manifest.py b/mercurial/manifest.py --- a/mercurial/manifest.py +++ b/mercurial/manifest.py @@ -32,6 +32,7 @@ repository, util as interfaceutil, ) +from .utils import dirstateutil parsers = policy.importmod(r'parsers') propertycache = util.propertycache @@ -494,7 +495,7 @@ @propertycache def _dirs(self): - return util.dirs(self) + return dirstateutil.dirs(self) def dirs(self): return self._dirs @@ -1104,7 +1105,7 @@ @propertycache def _alldirs(self): - return util.dirs(self) + return dirstateutil.dirs(self) def dirs(self): return self._alldirs diff --git a/mercurial/match.py b/mercurial/match.py --- a/mercurial/match.py +++ b/mercurial/match.py @@ -22,7 +22,10 @@ pycompat, util, ) -from .utils import stringutil +from .utils import ( + dirstateutil, + stringutil, +) rustmod = policy.importrust(r'filepatterns') @@ -595,7 +598,7 @@ @propertycache def _dirs(self): - return set(util.dirs(self._fileset)) + return set(dirstateutil.dirs(self._fileset)) def visitdir(self, dir): dir = normalizerootdir(dir, b'visitdir') @@ -626,9 +629,9 @@ return b'' % pycompat.bytestr(self._pats) -# This is basically a reimplementation of util.dirs that stores the children -# instead of just a count of them, plus a small optional optimization to avoid -# some directories we don't need. +# This is basically a reimplementation of dirstateutil.dirs that stores the +# children instead of just a count of them, plus a small optional optimization +# to avoid some directories we don't need. class _dirchildren(object): def __init__(self, paths, onlyinclude=None): self._dirs = {} @@ -760,7 +763,7 @@ @propertycache def _dirs(self): - return set(util.dirs(self._fileset)) + return set(dirstateutil.dirs(self._fileset)) def visitdir(self, dir): dir = normalizerootdir(dir, b'visitdir') @@ -1507,8 +1510,8 @@ p = set() # Add the parents as non-recursive/exact directories, since they must be # scanned to get to either the roots or the other exact directories. - p.update(util.dirs(d)) - p.update(util.dirs(r)) + p.update(dirstateutil.dirs(d)) + p.update(dirstateutil.dirs(r)) # FIXME: all uses of this function convert these to sets, do so before # returning. diff --git a/mercurial/repair.py b/mercurial/repair.py --- a/mercurial/repair.py +++ b/mercurial/repair.py @@ -28,7 +28,10 @@ pycompat, util, ) -from .utils import stringutil +from .utils import ( + dirstateutil, + stringutil, +) def backupbundle( @@ -476,7 +479,7 @@ if b'treemanifest' in repo.requirements: # This logic is safe if treemanifest isn't enabled, but also # pointless, so we skip it if treemanifest isn't enabled. - for dir in util.dirs(seenfiles): + for dir in dirstateutil.dirs(seenfiles): i = b'meta/%s/00manifest.i' % dir d = b'meta/%s/00manifest.d' % dir diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -57,11 +57,8 @@ stringutil, ) -rustdirs = policy.importrust(r'dirstate', r'Dirs') - base85 = policy.importmod(r'base85') osutil = policy.importmod(r'osutil') -parsers = policy.importmod(r'parsers') b85decode = base85.b85decode b85encode = base85.b85encode @@ -3494,54 +3491,6 @@ f.flush() -class dirs(object): - '''a multiset of directory names from a dirstate or manifest''' - - def __init__(self, map, skip=None): - self._dirs = {} - addpath = self.addpath - if isinstance(map, dict) and skip is not None: - for f, s in pycompat.iteritems(map): - if s[0] != skip: - addpath(f) - elif skip is not None: - raise error.ProgrammingError( - b"skip character is only supported with a dict source" - ) - else: - for f in map: - addpath(f) - - def addpath(self, path): - dirs = self._dirs - for base in finddirs(path): - if base in dirs: - dirs[base] += 1 - return - dirs[base] = 1 - - def delpath(self, path): - dirs = self._dirs - for base in finddirs(path): - if dirs[base] > 1: - dirs[base] -= 1 - return - del dirs[base] - - def __iter__(self): - return iter(self._dirs) - - def __contains__(self, d): - return d in self._dirs - - -if safehasattr(parsers, 'dirs'): - dirs = parsers.dirs - -if rustdirs is not None: - dirs = rustdirs - - def finddirs(path): pos = path.rfind(b'/') while pos != -1: diff --git a/mercurial/utils/dirstateutil.py b/mercurial/utils/dirstateutil.py new file mode 100644 --- /dev/null +++ b/mercurial/utils/dirstateutil.py @@ -0,0 +1,59 @@ +from __future__ import absolute_import + +from .. import ( + error, + policy, + pycompat, + util, +) + +rustdirs = policy.importrust(r'dirstate', r'Dirs') +parsers = policy.importmod(r'parsers') + + +class dirs(object): + '''a multiset of directory names from a dirstate or manifest''' + + def __init__(self, map, skip=None): + self._dirs = {} + addpath = self.addpath + if isinstance(map, dict) and skip is not None: + for f, s in pycompat.iteritems(map): + if s[0] != skip: + addpath(f) + elif skip is not None: + raise error.ProgrammingError( + b"skip character is only supported with a dict source" + ) + else: + for f in map: + addpath(f) + + def addpath(self, path): + dirs = self._dirs + for base in util.finddirs(path): + if base in dirs: + dirs[base] += 1 + return + dirs[base] = 1 + + def delpath(self, path): + dirs = self._dirs + for base in util.finddirs(path): + if dirs[base] > 1: + dirs[base] -= 1 + return + del dirs[base] + + def __iter__(self): + return iter(self._dirs) + + def __contains__(self, d): + return d in self._dirs + + +if util.safehasattr(parsers, 'dirs'): + dirs = parsers.dirs + +if rustdirs is not None: + dirs = rustdirs