comparison mercurial/pathutil.py @ 49964:445b4d819e9a

pathauditor: no need to normcase the paths The only thing normed paths are used is the key of the caching sets, so the only change of behavior will be that the checks will be repeated for paths that differ by case. If anything, it seems correct for the check to be repeated, in case that actually affects semantics, but the main reasoning is simplifying the code and making it a bit faster. It looks like the code originally comes from commit [081e795c60e0]: it looks like that commit tried to get rid of the existing norming, but presumably did this overly cautiously, preserving it for the cache keys, even though it was pointless even then.
author Arseniy Alekseyev <aalekseyev@janestreet.com>
date Fri, 06 Jan 2023 16:27:31 +0000
parents 44deb5a164dc
children 1b701d425c37
comparison
equal deleted inserted replaced
49963:44deb5a164dc 49964:445b4d819e9a
70 # type: (bytes, Optional[Any]) -> None 70 # type: (bytes, Optional[Any]) -> None
71 """Check the relative path. 71 """Check the relative path.
72 path may contain a pattern (e.g. foodir/**.txt)""" 72 path may contain a pattern (e.g. foodir/**.txt)"""
73 73
74 path = util.localpath(path) 74 path = util.localpath(path)
75 normpath = self.normcase(path) 75 if path in self.audited:
76 if normpath in self.audited:
77 return 76 return
78 # AIX ignores "/" at end of path, others raise EISDIR. 77 # AIX ignores "/" at end of path, others raise EISDIR.
79 if util.endswithsep(path): 78 if util.endswithsep(path):
80 raise error.InputError( 79 raise error.InputError(
81 _(b"path ends in directory separator: %s") % path 80 _(b"path ends in directory separator: %s") % path
107 raise error.InputError( 106 raise error.InputError(
108 _(b"path '%s' is inside nested repo %r") 107 _(b"path '%s' is inside nested repo %r")
109 % (path, pycompat.bytestr(base)) 108 % (path, pycompat.bytestr(base))
110 ) 109 )
111 110
112 normparts = util.splitpath(normpath)
113 assert len(parts) == len(normparts)
114
115 parts.pop() 111 parts.pop()
116 normparts.pop()
117 # It's important that we check the path parts starting from the root. 112 # It's important that we check the path parts starting from the root.
118 # We don't want to add "foo/bar/baz" to auditeddir before checking if 113 # We don't want to add "foo/bar/baz" to auditeddir before checking if
119 # there's a "foo/.hg" directory. This also means we won't accidentally 114 # there's a "foo/.hg" directory. This also means we won't accidentally
120 # traverse a symlink into some other filesystem (which is potentially 115 # traverse a symlink into some other filesystem (which is potentially
121 # expensive to access). 116 # expensive to access).
122 for i in range(len(parts)): 117 for i in range(len(parts)):
123 prefix = pycompat.ossep.join(parts[: i + 1]) 118 prefix = pycompat.ossep.join(parts[: i + 1])
124 normprefix = pycompat.ossep.join(normparts[: i + 1]) 119 if prefix in self.auditeddir:
125 if normprefix in self.auditeddir:
126 continue 120 continue
127 if self._realfs: 121 if self._realfs:
128 self._checkfs(prefix, path) 122 self._checkfs(prefix, path)
129 if self._cached: 123 if self._cached:
130 self.auditeddir.add(normprefix) 124 self.auditeddir.add(prefix)
131 125
132 if self._cached: 126 if self._cached:
133 self.audited.add(normpath) 127 self.audited.add(path)
134 128
135 def _checkfs(self, prefix, path): 129 def _checkfs(self, prefix, path):
136 # type: (bytes, bytes) -> None 130 # type: (bytes, bytes) -> None
137 """raise exception if a file system backed check fails""" 131 """raise exception if a file system backed check fails"""
138 curpath = os.path.join(self.root, prefix) 132 curpath = os.path.join(self.root, prefix)