##// END OF EJS Templates
match: fix NameError 'pat' on overflow of regex pattern length...
Yuya Nishihara -
r21191:a2f4ea82 stable
parent child Browse files
Show More
@@ -1,408 +1,408
1 1 # match.py - filename matching
2 2 #
3 3 # Copyright 2008, 2009 Matt Mackall <mpm@selenic.com> and others
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 import re
9 9 import util, pathutil
10 10 from i18n import _
11 11
12 12 def _rematcher(regex):
13 13 '''compile the regexp with the best available regexp engine and return a
14 14 matcher function'''
15 15 m = util.compilere(regex)
16 16 try:
17 17 # slightly faster, provided by facebook's re2 bindings
18 18 return m.test_match
19 19 except AttributeError:
20 20 return m.match
21 21
22 22 def _expandsets(kindpats, ctx):
23 23 '''Returns the kindpats list with the 'set' patterns expanded.'''
24 24 fset = set()
25 25 other = []
26 26
27 27 for kind, pat in kindpats:
28 28 if kind == 'set':
29 29 if not ctx:
30 30 raise util.Abort("fileset expression with no context")
31 31 s = ctx.getfileset(pat)
32 32 fset.update(s)
33 33 continue
34 34 other.append((kind, pat))
35 35 return fset, other
36 36
37 37 class match(object):
38 38 def __init__(self, root, cwd, patterns, include=[], exclude=[],
39 39 default='glob', exact=False, auditor=None, ctx=None):
40 40 """build an object to match a set of file patterns
41 41
42 42 arguments:
43 43 root - the canonical root of the tree you're matching against
44 44 cwd - the current working directory, if relevant
45 45 patterns - patterns to find
46 46 include - patterns to include (unless they are excluded)
47 47 exclude - patterns to exclude (even if they are included)
48 48 default - if a pattern in patterns has no explicit type, assume this one
49 49 exact - patterns are actually filenames (include/exclude still apply)
50 50
51 51 a pattern is one of:
52 52 'glob:<glob>' - a glob relative to cwd
53 53 're:<regexp>' - a regular expression
54 54 'path:<path>' - a path relative to repository root
55 55 'relglob:<glob>' - an unrooted glob (*.c matches C files in all dirs)
56 56 'relpath:<path>' - a path relative to cwd
57 57 'relre:<regexp>' - a regexp that needn't match the start of a name
58 58 'set:<fileset>' - a fileset expression
59 59 '<something>' - a pattern of the specified default type
60 60 """
61 61
62 62 self._root = root
63 63 self._cwd = cwd
64 64 self._files = [] # exact files and roots of patterns
65 65 self._anypats = bool(include or exclude)
66 66 self._ctx = ctx
67 67 self._always = False
68 68
69 69 if include:
70 70 kindpats = _normalize(include, 'glob', root, cwd, auditor)
71 71 self.includepat, im = _buildmatch(ctx, kindpats, '(?:/|$)')
72 72 if exclude:
73 73 kindpats = _normalize(exclude, 'glob', root, cwd, auditor)
74 74 self.excludepat, em = _buildmatch(ctx, kindpats, '(?:/|$)')
75 75 if exact:
76 76 if isinstance(patterns, list):
77 77 self._files = patterns
78 78 else:
79 79 self._files = list(patterns)
80 80 pm = self.exact
81 81 elif patterns:
82 82 kindpats = _normalize(patterns, default, root, cwd, auditor)
83 83 self._files = _roots(kindpats)
84 84 self._anypats = self._anypats or _anypats(kindpats)
85 85 self.patternspat, pm = _buildmatch(ctx, kindpats, '$')
86 86
87 87 if patterns or exact:
88 88 if include:
89 89 if exclude:
90 90 m = lambda f: im(f) and not em(f) and pm(f)
91 91 else:
92 92 m = lambda f: im(f) and pm(f)
93 93 else:
94 94 if exclude:
95 95 m = lambda f: not em(f) and pm(f)
96 96 else:
97 97 m = pm
98 98 else:
99 99 if include:
100 100 if exclude:
101 101 m = lambda f: im(f) and not em(f)
102 102 else:
103 103 m = im
104 104 else:
105 105 if exclude:
106 106 m = lambda f: not em(f)
107 107 else:
108 108 m = lambda f: True
109 109 self._always = True
110 110
111 111 self.matchfn = m
112 112 self._fmap = set(self._files)
113 113
114 114 def __call__(self, fn):
115 115 return self.matchfn(fn)
116 116 def __iter__(self):
117 117 for f in self._files:
118 118 yield f
119 119
120 120 # Callbacks related to how the matcher is used by dirstate.walk.
121 121 # Subscribers to these events must monkeypatch the matcher object.
122 122 def bad(self, f, msg):
123 123 '''Callback from dirstate.walk for each explicit file that can't be
124 124 found/accessed, with an error message.'''
125 125 pass
126 126
127 127 # If an explicitdir is set, it will be called when an explicitly listed
128 128 # directory is visited.
129 129 explicitdir = None
130 130
131 131 # If an traversedir is set, it will be called when a directory discovered
132 132 # by recursive traversal is visited.
133 133 traversedir = None
134 134
135 135 def rel(self, f):
136 136 '''Convert repo path back to path that is relative to cwd of matcher.'''
137 137 return util.pathto(self._root, self._cwd, f)
138 138
139 139 def files(self):
140 140 '''Explicitly listed files or patterns or roots:
141 141 if no patterns or .always(): empty list,
142 142 if exact: list exact files,
143 143 if not .anypats(): list all files and dirs,
144 144 else: optimal roots'''
145 145 return self._files
146 146
147 147 def exact(self, f):
148 148 '''Returns True if f is in .files().'''
149 149 return f in self._fmap
150 150
151 151 def anypats(self):
152 152 '''Matcher uses patterns or include/exclude.'''
153 153 return self._anypats
154 154
155 155 def always(self):
156 156 '''Matcher will match everything and .files() will be empty
157 157 - optimization might be possible and necessary.'''
158 158 return self._always
159 159
160 160 class exact(match):
161 161 def __init__(self, root, cwd, files):
162 162 match.__init__(self, root, cwd, files, exact=True)
163 163
164 164 class always(match):
165 165 def __init__(self, root, cwd):
166 166 match.__init__(self, root, cwd, [])
167 167 self._always = True
168 168
169 169 class narrowmatcher(match):
170 170 """Adapt a matcher to work on a subdirectory only.
171 171
172 172 The paths are remapped to remove/insert the path as needed:
173 173
174 174 >>> m1 = match('root', '', ['a.txt', 'sub/b.txt'])
175 175 >>> m2 = narrowmatcher('sub', m1)
176 176 >>> bool(m2('a.txt'))
177 177 False
178 178 >>> bool(m2('b.txt'))
179 179 True
180 180 >>> bool(m2.matchfn('a.txt'))
181 181 False
182 182 >>> bool(m2.matchfn('b.txt'))
183 183 True
184 184 >>> m2.files()
185 185 ['b.txt']
186 186 >>> m2.exact('b.txt')
187 187 True
188 188 >>> m2.rel('b.txt')
189 189 'b.txt'
190 190 >>> def bad(f, msg):
191 191 ... print "%s: %s" % (f, msg)
192 192 >>> m1.bad = bad
193 193 >>> m2.bad('x.txt', 'No such file')
194 194 sub/x.txt: No such file
195 195 """
196 196
197 197 def __init__(self, path, matcher):
198 198 self._root = matcher._root
199 199 self._cwd = matcher._cwd
200 200 self._path = path
201 201 self._matcher = matcher
202 202 self._always = matcher._always
203 203
204 204 self._files = [f[len(path) + 1:] for f in matcher._files
205 205 if f.startswith(path + "/")]
206 206 self._anypats = matcher._anypats
207 207 self.matchfn = lambda fn: matcher.matchfn(self._path + "/" + fn)
208 208 self._fmap = set(self._files)
209 209
210 210 def bad(self, f, msg):
211 211 self._matcher.bad(self._path + "/" + f, msg)
212 212
213 213 def patkind(pattern, default=None):
214 214 '''If pattern is 'kind:pat' with a known kind, return kind.'''
215 215 return _patsplit(pattern, default)[0]
216 216
217 217 def _patsplit(pattern, default):
218 218 """Split a string into the optional pattern kind prefix and the actual
219 219 pattern."""
220 220 if ':' in pattern:
221 221 kind, pat = pattern.split(':', 1)
222 222 if kind in ('re', 'glob', 'path', 'relglob', 'relpath', 'relre',
223 223 'listfile', 'listfile0', 'set'):
224 224 return kind, pat
225 225 return default, pattern
226 226
227 227 def _globre(pat):
228 228 r'''Convert an extended glob string to a regexp string.
229 229
230 230 >>> print _globre(r'?')
231 231 .
232 232 >>> print _globre(r'*')
233 233 [^/]*
234 234 >>> print _globre(r'**')
235 235 .*
236 236 >>> print _globre(r'[a*?!^][^b][!c]')
237 237 [a*?!^][\^b][^c]
238 238 >>> print _globre(r'{a,b}')
239 239 (?:a|b)
240 240 >>> print _globre(r'.\*\?')
241 241 \.\*\?
242 242 '''
243 243 i, n = 0, len(pat)
244 244 res = ''
245 245 group = 0
246 246 escape = re.escape
247 247 def peek():
248 248 return i < n and pat[i]
249 249 while i < n:
250 250 c = pat[i]
251 251 i += 1
252 252 if c not in '*?[{},\\':
253 253 res += escape(c)
254 254 elif c == '*':
255 255 if peek() == '*':
256 256 i += 1
257 257 res += '.*'
258 258 else:
259 259 res += '[^/]*'
260 260 elif c == '?':
261 261 res += '.'
262 262 elif c == '[':
263 263 j = i
264 264 if j < n and pat[j] in '!]':
265 265 j += 1
266 266 while j < n and pat[j] != ']':
267 267 j += 1
268 268 if j >= n:
269 269 res += '\\['
270 270 else:
271 271 stuff = pat[i:j].replace('\\','\\\\')
272 272 i = j + 1
273 273 if stuff[0] == '!':
274 274 stuff = '^' + stuff[1:]
275 275 elif stuff[0] == '^':
276 276 stuff = '\\' + stuff
277 277 res = '%s[%s]' % (res, stuff)
278 278 elif c == '{':
279 279 group += 1
280 280 res += '(?:'
281 281 elif c == '}' and group:
282 282 res += ')'
283 283 group -= 1
284 284 elif c == ',' and group:
285 285 res += '|'
286 286 elif c == '\\':
287 287 p = peek()
288 288 if p:
289 289 i += 1
290 290 res += escape(p)
291 291 else:
292 292 res += escape(c)
293 293 else:
294 294 res += escape(c)
295 295 return res
296 296
297 297 def _regex(kind, pat, globsuffix):
298 298 '''Convert a (normalized) pattern of any kind into a regular expression.
299 299 globsuffix is appended to the regexp of globs.'''
300 300 if not pat:
301 301 return ''
302 302 if kind == 're':
303 303 return pat
304 304 if kind == 'path':
305 305 return '^' + re.escape(pat) + '(?:/|$)'
306 306 if kind == 'relglob':
307 307 return '(?:|.*/)' + _globre(pat) + globsuffix
308 308 if kind == 'relpath':
309 309 return re.escape(pat) + '(?:/|$)'
310 310 if kind == 'relre':
311 311 if pat.startswith('^'):
312 312 return pat
313 313 return '.*' + pat
314 314 return _globre(pat) + globsuffix
315 315
316 316 def _buildmatch(ctx, kindpats, globsuffix):
317 317 '''Return regexp string and a matcher function for kindpats.
318 318 globsuffix is appended to the regexp of globs.'''
319 319 fset, kindpats = _expandsets(kindpats, ctx)
320 320 if not kindpats:
321 321 return "", fset.__contains__
322 322
323 323 regex, mf = _buildregexmatch(kindpats, globsuffix)
324 324 if fset:
325 325 return regex, lambda f: f in fset or mf(f)
326 326 return regex, mf
327 327
328 328 def _buildregexmatch(kindpats, globsuffix):
329 329 """Build a match function from a list of kinds and kindpats,
330 330 return regexp string and a matcher function."""
331 331 try:
332 332 regex = '(?:%s)' % '|'.join([_regex(k, p, globsuffix)
333 333 for (k, p) in kindpats])
334 334 if len(regex) > 20000:
335 335 raise OverflowError
336 336 return regex, _rematcher(regex)
337 337 except OverflowError:
338 338 # We're using a Python with a tiny regex engine and we
339 339 # made it explode, so we'll divide the pattern list in two
340 340 # until it works
341 341 l = len(kindpats)
342 342 if l < 2:
343 343 raise
344 344 regexa, a = _buildregexmatch(kindpats[:l//2], globsuffix)
345 345 regexb, b = _buildregexmatch(kindpats[l//2:], globsuffix)
346 return pat, lambda s: a(s) or b(s)
346 return regex, lambda s: a(s) or b(s)
347 347 except re.error:
348 348 for k, p in kindpats:
349 349 try:
350 350 _rematcher('(?:%s)' % _regex(k, p, globsuffix))
351 351 except re.error:
352 352 raise util.Abort(_("invalid pattern (%s): %s") % (k, p))
353 353 raise util.Abort(_("invalid pattern"))
354 354
355 355 def _normalize(patterns, default, root, cwd, auditor):
356 356 '''Convert 'kind:pat' from the patterns list to tuples with kind and
357 357 normalized and rooted patterns and with listfiles expanded.'''
358 358 kindpats = []
359 359 for kind, pat in [_patsplit(p, default) for p in patterns]:
360 360 if kind in ('glob', 'relpath'):
361 361 pat = pathutil.canonpath(root, cwd, pat, auditor)
362 362 elif kind in ('relglob', 'path'):
363 363 pat = util.normpath(pat)
364 364 elif kind in ('listfile', 'listfile0'):
365 365 try:
366 366 files = util.readfile(pat)
367 367 if kind == 'listfile0':
368 368 files = files.split('\0')
369 369 else:
370 370 files = files.splitlines()
371 371 files = [f for f in files if f]
372 372 except EnvironmentError:
373 373 raise util.Abort(_("unable to read file list (%s)") % pat)
374 374 kindpats += _normalize(files, default, root, cwd, auditor)
375 375 continue
376 376 # else: re or relre - which cannot be normalized
377 377 kindpats.append((kind, pat))
378 378 return kindpats
379 379
380 380 def _roots(kindpats):
381 381 '''return roots and exact explicitly listed files from patterns
382 382
383 383 >>> _roots([('glob', 'g/*'), ('glob', 'g'), ('glob', 'g*')])
384 384 ['g', 'g', '.']
385 385 >>> _roots([('relpath', 'r'), ('path', 'p/p'), ('path', '')])
386 386 ['r', 'p/p', '.']
387 387 >>> _roots([('relglob', 'rg*'), ('re', 're/'), ('relre', 'rr')])
388 388 ['.', '.', '.']
389 389 '''
390 390 r = []
391 391 for kind, pat in kindpats:
392 392 if kind == 'glob': # find the non-glob prefix
393 393 root = []
394 394 for p in pat.split('/'):
395 395 if '[' in p or '{' in p or '*' in p or '?' in p:
396 396 break
397 397 root.append(p)
398 398 r.append('/'.join(root) or '.')
399 399 elif kind in ('relpath', 'path'):
400 400 r.append(pat or '.')
401 401 else: # relglob, re, relre
402 402 r.append('.')
403 403 return r
404 404
405 405 def _anypats(kindpats):
406 406 for kind, pat in kindpats:
407 407 if kind in ('glob', 're', 'relglob', 'relre', 'set'):
408 408 return True
@@ -1,333 +1,344
1 1 $ hg init t
2 2 $ cd t
3 3 $ mkdir -p beans
4 4 $ for b in kidney navy turtle borlotti black pinto; do
5 5 > echo $b > beans/$b
6 6 > done
7 7 $ mkdir -p mammals/Procyonidae
8 8 $ for m in cacomistle coatimundi raccoon; do
9 9 > echo $m > mammals/Procyonidae/$m
10 10 > done
11 11 $ echo skunk > mammals/skunk
12 12 $ echo fennel > fennel
13 13 $ echo fenugreek > fenugreek
14 14 $ echo fiddlehead > fiddlehead
15 15 $ hg addremove
16 16 adding beans/black
17 17 adding beans/borlotti
18 18 adding beans/kidney
19 19 adding beans/navy
20 20 adding beans/pinto
21 21 adding beans/turtle
22 22 adding fennel
23 23 adding fenugreek
24 24 adding fiddlehead
25 25 adding mammals/Procyonidae/cacomistle
26 26 adding mammals/Procyonidae/coatimundi
27 27 adding mammals/Procyonidae/raccoon
28 28 adding mammals/skunk
29 29 $ hg commit -m "commit #0"
30 30
31 31 $ hg debugwalk
32 32 f beans/black beans/black
33 33 f beans/borlotti beans/borlotti
34 34 f beans/kidney beans/kidney
35 35 f beans/navy beans/navy
36 36 f beans/pinto beans/pinto
37 37 f beans/turtle beans/turtle
38 38 f fennel fennel
39 39 f fenugreek fenugreek
40 40 f fiddlehead fiddlehead
41 41 f mammals/Procyonidae/cacomistle mammals/Procyonidae/cacomistle
42 42 f mammals/Procyonidae/coatimundi mammals/Procyonidae/coatimundi
43 43 f mammals/Procyonidae/raccoon mammals/Procyonidae/raccoon
44 44 f mammals/skunk mammals/skunk
45 45 $ hg debugwalk -I.
46 46 f beans/black beans/black
47 47 f beans/borlotti beans/borlotti
48 48 f beans/kidney beans/kidney
49 49 f beans/navy beans/navy
50 50 f beans/pinto beans/pinto
51 51 f beans/turtle beans/turtle
52 52 f fennel fennel
53 53 f fenugreek fenugreek
54 54 f fiddlehead fiddlehead
55 55 f mammals/Procyonidae/cacomistle mammals/Procyonidae/cacomistle
56 56 f mammals/Procyonidae/coatimundi mammals/Procyonidae/coatimundi
57 57 f mammals/Procyonidae/raccoon mammals/Procyonidae/raccoon
58 58 f mammals/skunk mammals/skunk
59 59
60 60 $ cd mammals
61 61 $ hg debugwalk
62 62 f beans/black ../beans/black
63 63 f beans/borlotti ../beans/borlotti
64 64 f beans/kidney ../beans/kidney
65 65 f beans/navy ../beans/navy
66 66 f beans/pinto ../beans/pinto
67 67 f beans/turtle ../beans/turtle
68 68 f fennel ../fennel
69 69 f fenugreek ../fenugreek
70 70 f fiddlehead ../fiddlehead
71 71 f mammals/Procyonidae/cacomistle Procyonidae/cacomistle
72 72 f mammals/Procyonidae/coatimundi Procyonidae/coatimundi
73 73 f mammals/Procyonidae/raccoon Procyonidae/raccoon
74 74 f mammals/skunk skunk
75 75 $ hg debugwalk -X ../beans
76 76 f fennel ../fennel
77 77 f fenugreek ../fenugreek
78 78 f fiddlehead ../fiddlehead
79 79 f mammals/Procyonidae/cacomistle Procyonidae/cacomistle
80 80 f mammals/Procyonidae/coatimundi Procyonidae/coatimundi
81 81 f mammals/Procyonidae/raccoon Procyonidae/raccoon
82 82 f mammals/skunk skunk
83 83 $ hg debugwalk -I '*k'
84 84 f mammals/skunk skunk
85 85 $ hg debugwalk -I 'glob:*k'
86 86 f mammals/skunk skunk
87 87 $ hg debugwalk -I 'relglob:*k'
88 88 f beans/black ../beans/black
89 89 f fenugreek ../fenugreek
90 90 f mammals/skunk skunk
91 91 $ hg debugwalk -I 'relglob:*k' .
92 92 f mammals/skunk skunk
93 93 $ hg debugwalk -I 're:.*k$'
94 94 f beans/black ../beans/black
95 95 f fenugreek ../fenugreek
96 96 f mammals/skunk skunk
97 97 $ hg debugwalk -I 'relre:.*k$'
98 98 f beans/black ../beans/black
99 99 f fenugreek ../fenugreek
100 100 f mammals/skunk skunk
101 101 $ hg debugwalk -I 'path:beans'
102 102 f beans/black ../beans/black
103 103 f beans/borlotti ../beans/borlotti
104 104 f beans/kidney ../beans/kidney
105 105 f beans/navy ../beans/navy
106 106 f beans/pinto ../beans/pinto
107 107 f beans/turtle ../beans/turtle
108 108 $ hg debugwalk -I 'relpath:detour/../../beans'
109 109 f beans/black ../beans/black
110 110 f beans/borlotti ../beans/borlotti
111 111 f beans/kidney ../beans/kidney
112 112 f beans/navy ../beans/navy
113 113 f beans/pinto ../beans/pinto
114 114 f beans/turtle ../beans/turtle
115 115 $ hg debugwalk .
116 116 f mammals/Procyonidae/cacomistle Procyonidae/cacomistle
117 117 f mammals/Procyonidae/coatimundi Procyonidae/coatimundi
118 118 f mammals/Procyonidae/raccoon Procyonidae/raccoon
119 119 f mammals/skunk skunk
120 120 $ hg debugwalk -I.
121 121 f mammals/Procyonidae/cacomistle Procyonidae/cacomistle
122 122 f mammals/Procyonidae/coatimundi Procyonidae/coatimundi
123 123 f mammals/Procyonidae/raccoon Procyonidae/raccoon
124 124 f mammals/skunk skunk
125 125 $ hg debugwalk Procyonidae
126 126 f mammals/Procyonidae/cacomistle Procyonidae/cacomistle
127 127 f mammals/Procyonidae/coatimundi Procyonidae/coatimundi
128 128 f mammals/Procyonidae/raccoon Procyonidae/raccoon
129 129
130 130 $ cd Procyonidae
131 131 $ hg debugwalk .
132 132 f mammals/Procyonidae/cacomistle cacomistle
133 133 f mammals/Procyonidae/coatimundi coatimundi
134 134 f mammals/Procyonidae/raccoon raccoon
135 135 $ hg debugwalk ..
136 136 f mammals/Procyonidae/cacomistle cacomistle
137 137 f mammals/Procyonidae/coatimundi coatimundi
138 138 f mammals/Procyonidae/raccoon raccoon
139 139 f mammals/skunk ../skunk
140 140 $ cd ..
141 141
142 142 $ hg debugwalk ../beans
143 143 f beans/black ../beans/black
144 144 f beans/borlotti ../beans/borlotti
145 145 f beans/kidney ../beans/kidney
146 146 f beans/navy ../beans/navy
147 147 f beans/pinto ../beans/pinto
148 148 f beans/turtle ../beans/turtle
149 149 $ hg debugwalk .
150 150 f mammals/Procyonidae/cacomistle Procyonidae/cacomistle
151 151 f mammals/Procyonidae/coatimundi Procyonidae/coatimundi
152 152 f mammals/Procyonidae/raccoon Procyonidae/raccoon
153 153 f mammals/skunk skunk
154 154 $ hg debugwalk .hg
155 155 abort: path 'mammals/.hg' is inside nested repo 'mammals' (glob)
156 156 [255]
157 157 $ hg debugwalk ../.hg
158 158 abort: path contains illegal component: .hg
159 159 [255]
160 160 $ cd ..
161 161
162 162 $ hg debugwalk -Ibeans
163 163 f beans/black beans/black
164 164 f beans/borlotti beans/borlotti
165 165 f beans/kidney beans/kidney
166 166 f beans/navy beans/navy
167 167 f beans/pinto beans/pinto
168 168 f beans/turtle beans/turtle
169 169 $ hg debugwalk -I '{*,{b,m}*/*}k'
170 170 f beans/black beans/black
171 171 f fenugreek fenugreek
172 172 f mammals/skunk mammals/skunk
173 173 $ hg debugwalk 'glob:mammals/../beans/b*'
174 174 f beans/black beans/black
175 175 f beans/borlotti beans/borlotti
176 176 $ hg debugwalk '-X*/Procyonidae' mammals
177 177 f mammals/skunk mammals/skunk
178 178 $ hg debugwalk path:mammals
179 179 f mammals/Procyonidae/cacomistle mammals/Procyonidae/cacomistle
180 180 f mammals/Procyonidae/coatimundi mammals/Procyonidae/coatimundi
181 181 f mammals/Procyonidae/raccoon mammals/Procyonidae/raccoon
182 182 f mammals/skunk mammals/skunk
183 183 $ hg debugwalk ..
184 184 abort: .. not under root '$TESTTMP/t' (glob)
185 185 [255]
186 186 $ hg debugwalk beans/../..
187 187 abort: beans/../.. not under root '$TESTTMP/t' (glob)
188 188 [255]
189 189 $ hg debugwalk .hg
190 190 abort: path contains illegal component: .hg
191 191 [255]
192 192 $ hg debugwalk beans/../.hg
193 193 abort: path contains illegal component: .hg
194 194 [255]
195 195 $ hg debugwalk beans/../.hg/data
196 196 abort: path contains illegal component: .hg/data (glob)
197 197 [255]
198 198 $ hg debugwalk beans/.hg
199 199 abort: path 'beans/.hg' is inside nested repo 'beans' (glob)
200 200 [255]
201 201
202 202 Test absolute paths:
203 203
204 204 $ hg debugwalk `pwd`/beans
205 205 f beans/black beans/black
206 206 f beans/borlotti beans/borlotti
207 207 f beans/kidney beans/kidney
208 208 f beans/navy beans/navy
209 209 f beans/pinto beans/pinto
210 210 f beans/turtle beans/turtle
211 211 $ hg debugwalk `pwd`/..
212 212 abort: $TESTTMP/t/.. not under root '$TESTTMP/t' (glob)
213 213 [255]
214 214
215 215 Test patterns:
216 216
217 217 $ hg debugwalk glob:\*
218 218 f fennel fennel
219 219 f fenugreek fenugreek
220 220 f fiddlehead fiddlehead
221 221 #if eol-in-paths
222 222 $ echo glob:glob > glob:glob
223 223 $ hg addremove
224 224 adding glob:glob
225 225 warning: filename contains ':', which is reserved on Windows: 'glob:glob'
226 226 $ hg debugwalk glob:\*
227 227 f fennel fennel
228 228 f fenugreek fenugreek
229 229 f fiddlehead fiddlehead
230 230 f glob:glob glob:glob
231 231 $ hg debugwalk glob:glob
232 232 glob: No such file or directory
233 233 $ hg debugwalk glob:glob:glob
234 234 f glob:glob glob:glob exact
235 235 $ hg debugwalk path:glob:glob
236 236 f glob:glob glob:glob exact
237 237 $ rm glob:glob
238 238 $ hg addremove
239 239 removing glob:glob
240 240 #endif
241 241
242 242 $ hg debugwalk 'glob:**e'
243 243 f beans/turtle beans/turtle
244 244 f mammals/Procyonidae/cacomistle mammals/Procyonidae/cacomistle
245 245
246 246 $ hg debugwalk 're:.*[kb]$'
247 247 f beans/black beans/black
248 248 f fenugreek fenugreek
249 249 f mammals/skunk mammals/skunk
250 250
251 251 $ hg debugwalk path:beans/black
252 252 f beans/black beans/black exact
253 253 $ hg debugwalk path:beans//black
254 254 f beans/black beans/black exact
255 255
256 256 $ hg debugwalk relglob:Procyonidae
257 257 $ hg debugwalk 'relglob:Procyonidae/**'
258 258 f mammals/Procyonidae/cacomistle mammals/Procyonidae/cacomistle
259 259 f mammals/Procyonidae/coatimundi mammals/Procyonidae/coatimundi
260 260 f mammals/Procyonidae/raccoon mammals/Procyonidae/raccoon
261 261 $ hg debugwalk 'relglob:Procyonidae/**' fennel
262 262 f fennel fennel exact
263 263 f mammals/Procyonidae/cacomistle mammals/Procyonidae/cacomistle
264 264 f mammals/Procyonidae/coatimundi mammals/Procyonidae/coatimundi
265 265 f mammals/Procyonidae/raccoon mammals/Procyonidae/raccoon
266 266 $ hg debugwalk beans 'glob:beans/*'
267 267 f beans/black beans/black
268 268 f beans/borlotti beans/borlotti
269 269 f beans/kidney beans/kidney
270 270 f beans/navy beans/navy
271 271 f beans/pinto beans/pinto
272 272 f beans/turtle beans/turtle
273 273 $ hg debugwalk 'glob:mamm**'
274 274 f mammals/Procyonidae/cacomistle mammals/Procyonidae/cacomistle
275 275 f mammals/Procyonidae/coatimundi mammals/Procyonidae/coatimundi
276 276 f mammals/Procyonidae/raccoon mammals/Procyonidae/raccoon
277 277 f mammals/skunk mammals/skunk
278 278 $ hg debugwalk 'glob:mamm**' fennel
279 279 f fennel fennel exact
280 280 f mammals/Procyonidae/cacomistle mammals/Procyonidae/cacomistle
281 281 f mammals/Procyonidae/coatimundi mammals/Procyonidae/coatimundi
282 282 f mammals/Procyonidae/raccoon mammals/Procyonidae/raccoon
283 283 f mammals/skunk mammals/skunk
284 284 $ hg debugwalk 'glob:j*'
285 285 $ hg debugwalk NOEXIST
286 286 NOEXIST: * (glob)
287 287
288 288 #if fifo
289 289 $ mkfifo fifo
290 290 $ hg debugwalk fifo
291 291 fifo: unsupported file type (type is fifo)
292 292 #endif
293 293
294 294 $ rm fenugreek
295 295 $ hg debugwalk fenugreek
296 296 f fenugreek fenugreek exact
297 297 $ hg rm fenugreek
298 298 $ hg debugwalk fenugreek
299 299 f fenugreek fenugreek exact
300 300 $ touch new
301 301 $ hg debugwalk new
302 302 f new new exact
303 303
304 304 $ mkdir ignored
305 305 $ touch ignored/file
306 306 $ echo '^ignored$' > .hgignore
307 307 $ hg debugwalk ignored
308 308 $ hg debugwalk ignored/file
309 309 f ignored/file ignored/file exact
310 310
311 311 Test listfile and listfile0
312 312
313 313 $ python -c "file('listfile0', 'wb').write('fenugreek\0new\0')"
314 314 $ hg debugwalk -I 'listfile0:listfile0'
315 315 f fenugreek fenugreek
316 316 f new new
317 317 $ python -c "file('listfile', 'wb').write('fenugreek\nnew\r\nmammals/skunk\n')"
318 318 $ hg debugwalk -I 'listfile:listfile'
319 319 f fenugreek fenugreek
320 320 f mammals/skunk mammals/skunk
321 321 f new new
322 322
323 323 $ cd ..
324 324 $ hg debugwalk -R t t/mammals/skunk
325 325 f mammals/skunk t/mammals/skunk exact
326 326 $ mkdir t2
327 327 $ cd t2
328 328 $ hg debugwalk -R ../t ../t/mammals/skunk
329 329 f mammals/skunk ../t/mammals/skunk exact
330 330 $ hg debugwalk --cwd ../t mammals/skunk
331 331 f mammals/skunk mammals/skunk exact
332 332
333 333 $ cd ..
334
335 Test split patterns on overflow
336
337 $ cd t
338 $ echo fennel > overflow.list
339 $ python -c "for i in xrange(20000 / 100): print 'x' * 100" >> overflow.list
340 $ echo fenugreek >> overflow.list
341 $ hg debugwalk 'listfile:overflow.list' 2>&1 | grep -v '^xxx'
342 f fennel fennel exact
343 f fenugreek fenugreek exact
344 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now