comparison mercurial/util.py @ 5200:c7e8fe11f34a

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.
author Alexis S. L. Carvalho <alexis@cecm.usp.br>
date Sat, 18 Aug 2007 21:36:10 -0300
parents 9374373fb727
children 1108c952cca1
comparison
equal deleted inserted replaced
5199:94e77a174f55 5200:c7e8fe11f34a
690 - contains ".." 690 - contains ".."
691 - traverses a symlink (e.g. a/symlink_here/b) 691 - traverses a symlink (e.g. a/symlink_here/b)
692 - inside a nested repository''' 692 - inside a nested repository'''
693 693
694 def __init__(self, root): 694 def __init__(self, root):
695 self.audited = {} 695 self.audited = set()
696 self.auditeddir = set()
696 self.root = root 697 self.root = root
697 698
698 def __call__(self, path): 699 def __call__(self, path):
699 if path in self.audited: 700 if path in self.audited:
700 return 701 return
718 (path, prefix)) 719 (path, prefix))
719 elif (stat.S_ISDIR(st.st_mode) and 720 elif (stat.S_ISDIR(st.st_mode) and
720 os.path.isdir(os.path.join(curpath, '.hg'))): 721 os.path.isdir(os.path.join(curpath, '.hg'))):
721 raise Abort(_('path %r is inside repo %r') % 722 raise Abort(_('path %r is inside repo %r') %
722 (path, prefix)) 723 (path, prefix))
723 self.audited[prefix] = True 724
725 prefixes = []
724 for c in strutil.rfindall(normpath, os.sep): 726 for c in strutil.rfindall(normpath, os.sep):
725 check(normpath[:c]) 727 prefix = normpath[:c]
726 self.audited[path] = True 728 if prefix in self.auditeddir:
729 break
730 check(prefix)
731 prefixes.append(prefix)
732
733 self.audited.add(path)
734 # only add prefixes to the cache after checking everything: we don't
735 # want to add "foo/bar/baz" before checking if there's a "foo/.hg"
736 self.auditeddir.update(prefixes)
727 737
728 def _makelock_file(info, pathname): 738 def _makelock_file(info, pathname):
729 ld = os.open(pathname, os.O_CREAT | os.O_WRONLY | os.O_EXCL) 739 ld = os.open(pathname, os.O_CREAT | os.O_WRONLY | os.O_EXCL)
730 os.write(ld, info) 740 os.write(ld, info)
731 os.close(ld) 741 os.close(ld)