45 normpath = self.normcase(path) |
46 normpath = self.normcase(path) |
46 if normpath in self.audited: |
47 if normpath in self.audited: |
47 return |
48 return |
48 # AIX ignores "/" at end of path, others raise EISDIR. |
49 # AIX ignores "/" at end of path, others raise EISDIR. |
49 if util.endswithsep(path): |
50 if util.endswithsep(path): |
50 raise util.Abort(_("path ends in directory separator: %s") % path) |
51 raise error.Abort(_("path ends in directory separator: %s") % path) |
51 parts = util.splitpath(path) |
52 parts = util.splitpath(path) |
52 if (os.path.splitdrive(path)[0] |
53 if (os.path.splitdrive(path)[0] |
53 or _lowerclean(parts[0]) in ('.hg', '.hg.', '') |
54 or _lowerclean(parts[0]) in ('.hg', '.hg.', '') |
54 or os.pardir in parts): |
55 or os.pardir in parts): |
55 raise util.Abort(_("path contains illegal component: %s") % path) |
56 raise error.Abort(_("path contains illegal component: %s") % path) |
56 # Windows shortname aliases |
57 # Windows shortname aliases |
57 for p in parts: |
58 for p in parts: |
58 if "~" in p: |
59 if "~" in p: |
59 first, last = p.split("~", 1) |
60 first, last = p.split("~", 1) |
60 if last.isdigit() and first.upper() in ["HG", "HG8B6C"]: |
61 if last.isdigit() and first.upper() in ["HG", "HG8B6C"]: |
61 raise util.Abort(_("path contains illegal component: %s") |
62 raise error.Abort(_("path contains illegal component: %s") |
62 % path) |
63 % path) |
63 if '.hg' in _lowerclean(path): |
64 if '.hg' in _lowerclean(path): |
64 lparts = [_lowerclean(p.lower()) for p in parts] |
65 lparts = [_lowerclean(p.lower()) for p in parts] |
65 for p in '.hg', '.hg.': |
66 for p in '.hg', '.hg.': |
66 if p in lparts[1:]: |
67 if p in lparts[1:]: |
67 pos = lparts.index(p) |
68 pos = lparts.index(p) |
68 base = os.path.join(*parts[:pos]) |
69 base = os.path.join(*parts[:pos]) |
69 raise util.Abort(_("path '%s' is inside nested repo %r") |
70 raise error.Abort(_("path '%s' is inside nested repo %r") |
70 % (path, base)) |
71 % (path, base)) |
71 |
72 |
72 normparts = util.splitpath(normpath) |
73 normparts = util.splitpath(normpath) |
73 assert len(parts) == len(normparts) |
74 assert len(parts) == len(normparts) |
74 |
75 |
88 # They must be ignored for patterns can be checked too. |
89 # They must be ignored for patterns can be checked too. |
89 if err.errno not in (errno.ENOENT, errno.ENOTDIR, errno.EINVAL): |
90 if err.errno not in (errno.ENOENT, errno.ENOTDIR, errno.EINVAL): |
90 raise |
91 raise |
91 else: |
92 else: |
92 if stat.S_ISLNK(st.st_mode): |
93 if stat.S_ISLNK(st.st_mode): |
93 raise util.Abort( |
94 raise error.Abort( |
94 _('path %r traverses symbolic link %r') |
95 _('path %r traverses symbolic link %r') |
95 % (path, prefix)) |
96 % (path, prefix)) |
96 elif (stat.S_ISDIR(st.st_mode) and |
97 elif (stat.S_ISDIR(st.st_mode) and |
97 os.path.isdir(os.path.join(curpath, '.hg'))): |
98 os.path.isdir(os.path.join(curpath, '.hg'))): |
98 if not self.callback or not self.callback(curpath): |
99 if not self.callback or not self.callback(curpath): |
99 raise util.Abort(_("path '%s' is inside nested " |
100 raise error.Abort(_("path '%s' is inside nested " |
100 "repo %r") |
101 "repo %r") |
101 % (path, prefix)) |
102 % (path, prefix)) |
102 prefixes.append(normprefix) |
103 prefixes.append(normprefix) |
103 parts.pop() |
104 parts.pop() |
104 normparts.pop() |
105 normparts.pop() |
110 |
111 |
111 def check(self, path): |
112 def check(self, path): |
112 try: |
113 try: |
113 self(path) |
114 self(path) |
114 return True |
115 return True |
115 except (OSError, util.Abort): |
116 except (OSError, error.Abort): |
116 return False |
117 return False |
117 |
118 |
118 def canonpath(root, cwd, myname, auditor=None): |
119 def canonpath(root, cwd, myname, auditor=None): |
119 '''return the canonical path of myname, given cwd and root''' |
120 '''return the canonical path of myname, given cwd and root''' |
120 if util.endswithsep(root): |
121 if util.endswithsep(root): |
165 try: |
166 try: |
166 if cwd != root: |
167 if cwd != root: |
167 canonpath(root, root, myname, auditor) |
168 canonpath(root, root, myname, auditor) |
168 hint = (_("consider using '--cwd %s'") |
169 hint = (_("consider using '--cwd %s'") |
169 % os.path.relpath(root, cwd)) |
170 % os.path.relpath(root, cwd)) |
170 except util.Abort: |
171 except error.Abort: |
171 pass |
172 pass |
172 |
173 |
173 raise util.Abort(_("%s not under root '%s'") % (myname, root), |
174 raise error.Abort(_("%s not under root '%s'") % (myname, root), |
174 hint=hint) |
175 hint=hint) |
175 |
176 |
176 def normasprefix(path): |
177 def normasprefix(path): |
177 '''normalize the specified path as path prefix |
178 '''normalize the specified path as path prefix |
178 |
179 |