361 |
361 |
362 # self._root may end with a path separator when self._root == '/' |
362 # self._root may end with a path separator when self._root == '/' |
363 common_prefix_len = len(self._root) |
363 common_prefix_len = len(self._root) |
364 if not self._root.endswith(os.sep): |
364 if not self._root.endswith(os.sep): |
365 common_prefix_len += 1 |
365 common_prefix_len += 1 |
|
366 |
366 # recursion free walker, faster than os.walk. |
367 # recursion free walker, faster than os.walk. |
|
368 normpath = util.normpath |
|
369 listdir = os.listdir |
|
370 lstat = os.lstat |
|
371 bisect_left = bisect.bisect_left |
|
372 isdir = os.path.isdir |
|
373 pconvert = util.pconvert |
|
374 join = os.path.join |
|
375 s_isdir = stat.S_ISDIR |
|
376 supported = self._supported |
|
377 |
367 def findfiles(s): |
378 def findfiles(s): |
368 work = [s] |
379 work = [s] |
369 if directories: |
380 if directories: |
370 yield 'd', util.normpath(s[common_prefix_len:]), os.lstat(s) |
381 yield 'd', normpath(s[common_prefix_len:]), os.lstat(s) |
371 while work: |
382 while work: |
372 top = work.pop() |
383 top = work.pop() |
373 names = os.listdir(top) |
384 names = listdir(top) |
374 names.sort() |
385 names.sort() |
375 # nd is the top of the repository dir tree |
386 # nd is the top of the repository dir tree |
376 nd = util.normpath(top[common_prefix_len:]) |
387 nd = normpath(top[common_prefix_len:]) |
377 if nd == '.': |
388 if nd == '.': |
378 nd = '' |
389 nd = '' |
379 else: |
390 else: |
380 # do not recurse into a repo contained in this |
391 # do not recurse into a repo contained in this |
381 # one. use bisect to find .hg directory so speed |
392 # one. use bisect to find .hg directory so speed |
382 # is good on big directory. |
393 # is good on big directory. |
383 hg = bisect.bisect_left(names, '.hg') |
394 hg = bisect_left(names, '.hg') |
384 if hg < len(names) and names[hg] == '.hg': |
395 if hg < len(names) and names[hg] == '.hg': |
385 if os.path.isdir(os.path.join(top, '.hg')): |
396 if isdir(join(top, '.hg')): |
386 continue |
397 continue |
387 for f in names: |
398 for f in names: |
388 np = util.pconvert(os.path.join(nd, f)) |
399 np = pconvert(os.path.join(nd, f)) |
389 if seen(np): |
400 if seen(np): |
390 continue |
401 continue |
391 p = os.path.join(top, f) |
402 p = join(top, f) |
392 # don't trip over symlinks |
403 # don't trip over symlinks |
393 st = os.lstat(p) |
404 st = lstat(p) |
394 if stat.S_ISDIR(st.st_mode): |
405 if s_isdir(st.st_mode): |
395 if not ignore(np): |
406 if not ignore(np): |
396 work.append(p) |
407 work.append(p) |
397 if directories: |
408 if directories: |
398 yield 'd', np, st |
409 yield 'd', np, st |
399 if imatch(np) and np in dc: |
410 if imatch(np) and np in dc: |
400 yield 'm', np, st |
411 yield 'm', np, st |
401 elif imatch(np): |
412 elif imatch(np): |
402 if self._supported(np, st): |
413 if supported(np, st): |
403 yield 'f', np, st |
414 yield 'f', np, st |
404 elif np in dc: |
415 elif np in dc: |
405 yield 'm', np, st |
416 yield 'm', np, st |
406 |
417 |
407 known = {'.hg': 1} |
418 known = {'.hg': 1} |
427 self._ui.warn('%s: %s\n' % |
438 self._ui.warn('%s: %s\n' % |
428 (self.pathto(ff), inst.strerror)) |
439 (self.pathto(ff), inst.strerror)) |
429 elif badmatch and badmatch(ff) and imatch(nf): |
440 elif badmatch and badmatch(ff) and imatch(nf): |
430 yield 'b', ff, None |
441 yield 'b', ff, None |
431 continue |
442 continue |
432 if stat.S_ISDIR(st.st_mode): |
443 if s_isdir(st.st_mode): |
433 cmp1 = (lambda x, y: cmp(x[1], y[1])) |
444 cmp1 = (lambda x, y: cmp(x[1], y[1])) |
434 sorted_ = [ x for x in findfiles(f) ] |
445 sorted_ = [ x for x in findfiles(f) ] |
435 sorted_.sort(cmp1) |
446 sorted_.sort(cmp1) |
436 for e in sorted_: |
447 for e in sorted_: |
437 yield e |
448 yield e |
438 else: |
449 else: |
439 if not seen(nf) and match(nf): |
450 if not seen(nf) and match(nf): |
440 if self._supported(ff, st, verbose=True): |
451 if supported(ff, st, verbose=True): |
441 yield 'f', nf, st |
452 yield 'f', nf, st |
442 elif ff in dc: |
453 elif ff in dc: |
443 yield 'm', nf, st |
454 yield 'm', nf, st |
444 |
455 |
445 # step two run through anything left in the dc hash and yield |
456 # step two run through anything left in the dc hash and yield |