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) |