# HG changeset patch # User Arseniy Alekseyev # Date 1672850912 0 # Node ID 1b701d425c37752a3f9073aa988c27f59cd7ec03 # Parent 3aa8e569478a7229d953cb2a82744a773ff71e59 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 diff -r 3aa8e569478a -r 1b701d425c37 mercurial/pathutil.py --- 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