path_auditor: cache names of audited directories
We use a separate cache to avoid problems with
audit = path_auditor(repo.root)
audit("subrepo")
audit("subrepo/file")
whitelisting "subrepo" (which is fine) and then using the same whitelist
with "subrepo/file" (which is not fine).
Since we create a separate path_auditor for every path on the command line,
a "hg add dir/a dir/b dir/c" will still lstat dir 3 times just to audit
the paths.
--- a/mercurial/util.py Sat Aug 18 20:21:14 2007 +0200
+++ b/mercurial/util.py Sat Aug 18 21:36:10 2007 -0300
@@ -692,7 +692,8 @@
- inside a nested repository'''
def __init__(self, root):
- self.audited = {}
+ self.audited = set()
+ self.auditeddir = set()
self.root = root
def __call__(self, path):
@@ -720,10 +721,19 @@
os.path.isdir(os.path.join(curpath, '.hg'))):
raise Abort(_('path %r is inside repo %r') %
(path, prefix))
- self.audited[prefix] = True
+
+ prefixes = []
for c in strutil.rfindall(normpath, os.sep):
- check(normpath[:c])
- self.audited[path] = True
+ prefix = normpath[:c]
+ if prefix in self.auditeddir:
+ break
+ check(prefix)
+ prefixes.append(prefix)
+
+ self.audited.add(path)
+ # only add prefixes to the cache after checking everything: we don't
+ # want to add "foo/bar/baz" before checking if there's a "foo/.hg"
+ self.auditeddir.update(prefixes)
def _makelock_file(info, pathname):
ld = os.open(pathname, os.O_CREAT | os.O_WRONLY | os.O_EXCL)
--- a/tests/test-nested-repo Sat Aug 18 20:21:14 2007 +0200
+++ b/tests/test-nested-repo Sat Aug 18 21:36:10 2007 -0300
@@ -13,6 +13,10 @@
hg st b/x
hg add b/x
+echo '# should fail'
+hg add b b/x
+hg st
+
echo '# should arguably print nothing'
hg st b
--- a/tests/test-nested-repo.out Sat Aug 18 20:21:14 2007 +0200
+++ b/tests/test-nested-repo.out Sat Aug 18 21:36:10 2007 -0300
@@ -2,6 +2,8 @@
# should fail
abort: path 'b/x' is inside repo 'b'
abort: path 'b/x' is inside repo 'b'
+# should fail
+abort: path 'b/x' is inside repo 'b'
# should arguably print nothing
# should fail
abort: path 'b/a' is inside repo 'b'