comparison mercurial/scmutil.py @ 15674:7b7f03502b5a

merge with stable
author Matt Mackall <mpm@selenic.com>
date Fri, 16 Dec 2011 19:05:59 -0600
parents 18f1bb70462e 37a6e9765015
children 5b384b7f48d5
comparison
equal deleted inserted replaced
15660:c7b0bedbb07a 15674:7b7f03502b5a
74 def __init__(self, root, callback=None): 74 def __init__(self, root, callback=None):
75 self.audited = set() 75 self.audited = set()
76 self.auditeddir = set() 76 self.auditeddir = set()
77 self.root = root 77 self.root = root
78 self.callback = callback 78 self.callback = callback
79 if os.path.lexists(root) and not util.checkcase(root):
80 self.normcase = util.normcase
81 else:
82 self.normcase = lambda x: x
79 83
80 def __call__(self, path): 84 def __call__(self, path):
81 '''Check the relative path. 85 '''Check the relative path.
82 path may contain a pattern (e.g. foodir/**.txt)''' 86 path may contain a pattern (e.g. foodir/**.txt)'''
83 87
84 if path in self.audited: 88 normpath = self.normcase(path)
89 if normpath in self.audited:
85 return 90 return
86 # AIX ignores "/" at end of path, others raise EISDIR. 91 # AIX ignores "/" at end of path, others raise EISDIR.
87 if util.endswithsep(path): 92 if util.endswithsep(path):
88 raise util.Abort(_("path ends in directory separator: %s") % path) 93 raise util.Abort(_("path ends in directory separator: %s") % path)
89 normpath = os.path.normcase(path) 94 parts = util.splitpath(path)
90 parts = util.splitpath(normpath)
91 if (os.path.splitdrive(path)[0] 95 if (os.path.splitdrive(path)[0]
92 or parts[0].lower() in ('.hg', '.hg.', '') 96 or parts[0].lower() in ('.hg', '.hg.', '')
93 or os.pardir in parts): 97 or os.pardir in parts):
94 raise util.Abort(_("path contains illegal component: %s") % path) 98 raise util.Abort(_("path contains illegal component: %s") % path)
95 if '.hg' in path.lower(): 99 if '.hg' in path.lower():
99 pos = lparts.index(p) 103 pos = lparts.index(p)
100 base = os.path.join(*parts[:pos]) 104 base = os.path.join(*parts[:pos])
101 raise util.Abort(_("path '%s' is inside nested repo %r") 105 raise util.Abort(_("path '%s' is inside nested repo %r")
102 % (path, base)) 106 % (path, base))
103 107
108 normparts = util.splitpath(normpath)
109 assert len(parts) == len(normparts)
110
104 parts.pop() 111 parts.pop()
112 normparts.pop()
105 prefixes = [] 113 prefixes = []
106 while parts: 114 while parts:
107 prefix = os.sep.join(parts) 115 prefix = os.sep.join(parts)
108 if prefix in self.auditeddir: 116 normprefix = os.sep.join(normparts)
117 if normprefix in self.auditeddir:
109 break 118 break
110 curpath = os.path.join(self.root, prefix) 119 curpath = os.path.join(self.root, prefix)
111 try: 120 try:
112 st = os.lstat(curpath) 121 st = os.lstat(curpath)
113 except OSError, err: 122 except OSError, err:
123 elif (stat.S_ISDIR(st.st_mode) and 132 elif (stat.S_ISDIR(st.st_mode) and
124 os.path.isdir(os.path.join(curpath, '.hg'))): 133 os.path.isdir(os.path.join(curpath, '.hg'))):
125 if not self.callback or not self.callback(curpath): 134 if not self.callback or not self.callback(curpath):
126 raise util.Abort(_("path '%s' is inside nested repo %r") % 135 raise util.Abort(_("path '%s' is inside nested repo %r") %
127 (path, prefix)) 136 (path, prefix))
128 prefixes.append(prefix) 137 prefixes.append(normprefix)
129 parts.pop() 138 parts.pop()
130 139 normparts.pop()
131 self.audited.add(path) 140
141 self.audited.add(normpath)
132 # only add prefixes to the cache after checking everything: we don't 142 # only add prefixes to the cache after checking everything: we don't
133 # want to add "foo/bar/baz" before checking if there's a "foo/.hg" 143 # want to add "foo/bar/baz" before checking if there's a "foo/.hg"
134 self.auditeddir.update(prefixes) 144 self.auditeddir.update(prefixes)
135 145
136 class abstractopener(object): 146 class abstractopener(object):