path_auditor: cache names of audited directories
authorAlexis S. L. Carvalho <alexis@cecm.usp.br>
Sat, 18 Aug 2007 21:36:10 -0300
changeset 5200 c7e8fe11f34a
parent 5199 94e77a174f55
child 5202 1108c952cca1
child 5203 653790c2fa52
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.
mercurial/util.py
tests/test-nested-repo
tests/test-nested-repo.out
--- 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'