Mercurial > hg
diff mercurial/pathutil.py @ 49890:1b701d425c37
merge: short-circuit the _checkfs loop upon getting ENOENT
This reduces the number of [lstat] calls when updating from rev(-1) to
a rev with lots of files by a factor of several: for path foo/bar/baz/quux.txt
without this patch we're lstatting:
foo
foo/bar
foo/bar/baz
foo/bar/baz/quux.txt
and with this patch:
foo
foo/bar/baz/quux.txt
author | Arseniy Alekseyev <aalekseyev@janestreet.com> |
---|---|
date | Wed, 04 Jan 2023 16:48:32 +0000 |
parents | 445b4d819e9a |
children | 76d1e9f229fe |
line wrap: on
line diff
--- a/mercurial/pathutil.py Wed Jan 04 19:13:41 2023 +0000 +++ b/mercurial/pathutil.py Wed Jan 04 16:48:32 2023 +0000 @@ -119,20 +119,26 @@ if prefix in self.auditeddir: continue if self._realfs: - self._checkfs(prefix, path) + res = self._checkfs_exists(prefix, path) if self._cached: self.auditeddir.add(prefix) + if not res: + break if self._cached: self.audited.add(path) - def _checkfs(self, prefix, path): - # type: (bytes, bytes) -> None - """raise exception if a file system backed check fails""" + def _checkfs_exists(self, prefix, path): + # type: (bytes, bytes) -> bool + """raise exception if a file system backed check fails. + + Return a bool that indicates that the directory (or file) exists.""" curpath = os.path.join(self.root, prefix) try: st = os.lstat(curpath) except OSError as err: + if err.errno == errno.ENOENT: + return False # EINVAL can be raised as invalid path syntax under win32. # They must be ignored for patterns can be checked too. if err.errno not in (errno.ENOENT, errno.ENOTDIR, errno.EINVAL): @@ -150,6 +156,7 @@ if not self.callback or not self.callback(curpath): msg = _(b"path '%s' is inside nested repo %r") raise error.Abort(msg % (path, pycompat.bytestr(prefix))) + return True def check(self, path): # type: (bytes) -> bool