# HG changeset patch # User Martin von Zweigbergk # Date 2019-11-14 16:03:26 # Node ID 0b7733719d21b73822e39c408baa72870a46537e # Parent 2e017696181f1effb6ec41ca05a875670498e768 utils: move finddirs() to pathutil This is a follow-up to c21aca51b392 (utils: move the `dirs` definition in pathutil (API), 2019-11-06). finddirs() is closely related to dirs and used by it. Differential Revision: https://phab.mercurial-scm.org/D7388 diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -2080,7 +2080,7 @@ class workingfilectx(committablefilectx) # warned and backed up if wvfs.isdir(f) and not wvfs.islink(f): wvfs.rmtree(f, forcibly=True) - for p in reversed(list(util.finddirs(f))): + for p in reversed(list(pathutil.finddirs(f))): if wvfs.isfileorlink(p): wvfs.unlink(p) break diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py --- a/mercurial/debugcommands.py +++ b/mercurial/debugcommands.py @@ -59,6 +59,7 @@ from . import ( merge as mergemod, obsolete, obsutil, + pathutil, phases, policy, pvec, @@ -1343,7 +1344,7 @@ def debugignore(ui, repo, *files, **opts ignored = nf ignoredata = repo.dirstate._ignorefileandline(nf) else: - for p in util.finddirs(nf): + for p in pathutil.finddirs(nf): if ignore(p): ignored = p ignoredata = repo.dirstate._ignorefileandline(p) diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py --- a/mercurial/dirstate.py +++ b/mercurial/dirstate.py @@ -404,7 +404,7 @@ class dirstate(object): _(b'directory %r already in dirstate') % pycompat.bytestr(f) ) # shadows - for d in util.finddirs(f): + for d in pathutil.finddirs(f): if self._map.hastrackeddir(d): break entry = self._map.get(d) @@ -707,7 +707,7 @@ class dirstate(object): def _dirignore(self, f): if self._ignore(f): return True - for p in util.finddirs(f): + for p in pathutil.finddirs(f): if self._ignore(p): return True return False diff --git a/mercurial/hgweb/hgwebdir_mod.py b/mercurial/hgweb/hgwebdir_mod.py --- a/mercurial/hgweb/hgwebdir_mod.py +++ b/mercurial/hgweb/hgwebdir_mod.py @@ -32,6 +32,7 @@ from .. import ( error, extensions, hg, + pathutil, profiling, pycompat, registrar, @@ -436,7 +437,7 @@ class hgwebdir(object): def _virtualdirs(): # Check the full virtual path, and each parent yield virtual - for p in util.finddirs(virtual): + for p in pathutil.finddirs(virtual): yield p for virtualrepo in _virtualdirs(): diff --git a/mercurial/match.py b/mercurial/match.py --- a/mercurial/match.py +++ b/mercurial/match.py @@ -18,7 +18,6 @@ from . import ( encoding, error, pathutil, - pathutil, policy, pycompat, util, @@ -598,7 +597,8 @@ class patternmatcher(basematcher): dir in self._fileset or dir in self._dirs or any( - parentdir in self._fileset for parentdir in util.finddirs(dir) + parentdir in self._fileset + for parentdir in pathutil.finddirs(dir) ) ) @@ -643,7 +643,7 @@ class _dirchildren(object): @staticmethod def _findsplitdirs(path): # yields (dirname, basename) tuples, walking back to the root. This is - # very similar to util.finddirs, except: + # very similar to pathutil.finddirs, except: # - produces a (dirname, basename) tuple, not just 'dirname' # Unlike manifest._splittopdir, this does not suffix `dirname` with a # slash. @@ -681,7 +681,9 @@ class includematcher(basematcher): dir in self._roots or dir in self._dirs or dir in self._parents - or any(parentdir in self._roots for parentdir in util.finddirs(dir)) + or any( + parentdir in self._roots for parentdir in pathutil.finddirs(dir) + ) ) @propertycache @@ -706,7 +708,9 @@ class includematcher(basematcher): b'' in self._roots or dir in self._roots or dir in self._dirs - or any(parentdir in self._roots for parentdir in util.finddirs(dir)) + or any( + parentdir in self._roots for parentdir in pathutil.finddirs(dir) + ) ): return b'this' @@ -1073,7 +1077,7 @@ class prefixdirmatcher(basematcher): @propertycache def _pathdirs(self): - return set(util.finddirs(self._path)) + return set(pathutil.finddirs(self._path)) def visitdir(self, dir): if dir == self._path: diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -32,6 +32,7 @@ from . import ( filemerge, match as matchmod, obsutil, + pathutil, pycompat, scmutil, subrepoutil, @@ -813,7 +814,7 @@ class _unknowndirschecker(object): return False # Check for path prefixes that exist as unknown files. - for p in reversed(list(util.finddirs(f))): + for p in reversed(list(pathutil.finddirs(f))): if p in self._missingdircache: return if p in self._unknowndircache: @@ -947,7 +948,7 @@ def _checkunknownfiles(repo, wctx, mctx, backup = ( f in fileconflicts or f in pathconflicts - or any(p in pathconflicts for p in util.finddirs(f)) + or any(p in pathconflicts for p in pathutil.finddirs(f)) ) (flags,) = args actions[f] = (ACTION_GET, (flags, backup), msg) @@ -1077,7 +1078,7 @@ def _filesindirs(repo, manifest, dirs): in. """ for f in manifest: - for p in util.finddirs(f): + for p in pathutil.finddirs(f): if p in dirs: yield f, p break @@ -1116,7 +1117,7 @@ def checkpathconflicts(repo, wctx, mctx, ACTION_CREATED_MERGE, ): # This action may create a new local file. - createdfiledirs.update(util.finddirs(f)) + createdfiledirs.update(pathutil.finddirs(f)) if mf.hasdir(f): # The file aliases a local directory. This might be ok if all # the files in the local directory are being deleted. This @@ -1710,7 +1711,7 @@ def batchget(repo, mctx, wctx, wantfiled # with a directory this file is in, and if so, back that up. conflicting = f if not repo.wvfs.lexists(f): - for p in util.finddirs(f): + for p in pathutil.finddirs(f): if repo.wvfs.isfileorlink(p): conflicting = p break diff --git a/mercurial/pathutil.py b/mercurial/pathutil.py --- a/mercurial/pathutil.py +++ b/mercurial/pathutil.py @@ -275,6 +275,14 @@ def normasprefix(path): return path +def finddirs(path): + pos = path.rfind(b'/') + while pos != -1: + yield path[:pos] + pos = path.rfind(b'/', 0, pos) + yield b'' + + class dirs(object): '''a multiset of directory names from a set of file paths''' @@ -295,7 +303,7 @@ class dirs(object): def addpath(self, path): dirs = self._dirs - for base in util.finddirs(path): + for base in finddirs(path): if base.endswith(b'/'): raise ValueError( "found invalid consecutive slashes in path: %r" % base @@ -307,7 +315,7 @@ class dirs(object): def delpath(self, path): dirs = self._dirs - for base in util.finddirs(path): + for base in finddirs(path): if dirs[base] > 1: dirs[base] -= 1 return diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -964,7 +964,7 @@ def backuppath(ui, repo, filepath): ui.note(_(b'creating directory: %s\n') % origvfs.join(origbackupdir)) # Remove any files that conflict with the backup file's path - for f in reversed(list(util.finddirs(filepath))): + for f in reversed(list(pathutil.finddirs(filepath))): if origvfs.isfileorlink(f): ui.note(_(b'removing conflicting file: %s\n') % origvfs.join(f)) origvfs.unlink(f) diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -3491,14 +3491,6 @@ def debugstacktrace( f.flush() -def finddirs(path): - pos = path.rfind(b'/') - while pos != -1: - yield path[:pos] - pos = path.rfind(b'/', 0, pos) - yield b'' - - # convenient shortcut dst = debugstacktrace diff --git a/rust/hg-core/src/utils/files.rs b/rust/hg-core/src/utils/files.rs --- a/rust/hg-core/src/utils/files.rs +++ b/rust/hg-core/src/utils/files.rs @@ -119,7 +119,7 @@ mod tests { #[test] fn find_dirs_empty() { - // looks weird, but mercurial.util.finddirs(b"") yields b"" + // looks weird, but mercurial.pathutil.finddirs(b"") yields b"" let mut dirs = super::find_dirs(HgPath::new(b"")); assert_eq!(dirs.next(), Some(HgPath::new(b""))); assert_eq!(dirs.next(), None);