478 if nf in seen: |
479 if nf in seen: |
479 continue |
480 continue |
480 |
481 |
481 try: |
482 try: |
482 st = lstat(_join(nf)) |
483 st = lstat(_join(nf)) |
|
484 if isdir(st.st_mode): |
|
485 if not dirignore(nf): |
|
486 wadd(nf) |
|
487 else: |
|
488 seen[nf] = 1 |
|
489 if supported(ff, st.st_mode, verbose=True): |
|
490 yield nf, st |
|
491 elif nf in dmap: |
|
492 yield nf, None |
483 except OSError, inst: |
493 except OSError, inst: |
484 keep = False |
494 keep = False |
|
495 prefix = nf + "/" |
485 for fn in dmap: |
496 for fn in dmap: |
486 if nf == fn or (fn.startswith(nf) and fn[len(nf)] == '/'): |
497 if nf == fn or fn.startswith(prefix): |
487 keep = True |
498 keep = True |
488 break |
499 break |
489 if not keep: |
500 if not keep: |
490 if inst.errno != errno.ENOENT: |
501 if inst.errno != errno.ENOENT: |
491 fwarn(ff, inst.strerror) |
502 fwarn(ff, inst.strerror) |
492 elif badfn(ff, inst.strerror) and imatch(nf): |
503 elif badfn(ff, inst.strerror) and imatch(nf): |
493 yield nf, None |
504 yield nf, None |
494 continue |
|
495 |
|
496 if s_isdir(st.st_mode): |
|
497 if not dirignore(nf): |
|
498 wadd(nf) |
|
499 else: |
|
500 seen[nf] = 1 |
|
501 if supported(ff, st.st_mode, verbose=True): |
|
502 yield nf, st |
|
503 elif nf in dmap: |
|
504 yield nf, None |
|
505 |
505 |
506 # step 2: visit subdirectories |
506 # step 2: visit subdirectories |
507 while work: |
507 while work: |
508 nd = work.pop() |
508 nd = work.pop() |
509 if hasattr(match, 'dir'): |
509 if hasattr(match, 'dir'): |
510 match.dir(nd) |
510 match.dir(nd) |
511 entries = listdir(_join(nd), stat=True) |
511 entries = listdir(_join(nd), stat=True) |
512 # nd is the top of the repository dir tree |
|
513 if nd == '.': |
512 if nd == '.': |
514 nd = '' |
513 nd = '' |
515 else: |
514 else: |
516 # do not recurse into a repo contained in this |
515 # do not recurse into a repo contained in this |
517 # one. use bisect to find .hg directory so speed |
516 # one. use bisect to find .hg directory so speed |
518 # is good on big directory. |
517 # is good on big directory. |
519 hg = bisect_left(entries, ('.hg')) |
518 hg = bisect_left(entries, ('.hg')) |
520 if hg < len(entries) and entries[hg][0] == '.hg' \ |
519 if hg < len(entries) and entries[hg][0] == '.hg' \ |
521 and entries[hg][1] == stat.S_IFDIR: |
520 and entries[hg][1] == dirkind: |
522 continue |
521 continue |
523 for f, kind, st in entries: |
522 for f, kind, st in entries: |
524 nf = normalize(pconvert(join(nd, f))) |
523 nf = normalize(nd and (nd + "/" + f) or f) |
525 if nf in seen: |
524 if nf not in seen: |
526 continue |
525 seen[nf] = 1 |
527 seen[nf] = 1 |
526 if kind == dirkind: |
528 # don't trip over symlinks |
527 if not ignore(nf): |
529 if kind == stat.S_IFDIR: |
528 wadd(nf) |
530 if not ignore(nf): |
529 if nf in dmap and match(nf): |
531 wadd(nf) |
530 yield nf, None |
532 if nf in dmap and match(nf): |
531 elif imatch(nf): |
533 yield nf, None |
532 if supported(nf, st.st_mode): |
534 elif imatch(nf): |
533 yield nf, st |
535 if supported(nf, st.st_mode): |
534 elif nf in dmap: |
536 yield nf, st |
535 yield nf, None |
537 elif nf in dmap: |
|
538 yield nf, None |
|
539 |
536 |
540 # step 3: report unseen items in the dmap hash |
537 # step 3: report unseen items in the dmap hash |
541 for f in util.sort(dmap): |
538 for f in util.sort(dmap): |
542 if f in seen or not match(f): |
539 if f not in seen and match(f): |
543 continue |
540 try: |
544 seen[f] = 1 |
541 st = lstat(_join(f)) |
545 try: |
542 if supported(f, st.st_mode): |
546 st = lstat(_join(f)) |
543 yield f, st |
547 if supported(f, st.st_mode): |
544 continue |
548 yield f, st |
545 except OSError, inst: |
549 continue |
546 if inst.errno not in (errno.ENOENT, errno.ENOTDIR): |
550 except OSError, inst: |
547 raise |
551 if inst.errno not in (errno.ENOENT, errno.ENOTDIR): |
548 yield f, None |
552 raise |
|
553 yield f, None |
|
554 |
549 |
555 def status(self, match, ignored, clean, unknown): |
550 def status(self, match, ignored, clean, unknown): |
556 listignored, listclean, listunknown = ignored, clean, unknown |
551 listignored, listclean, listunknown = ignored, clean, unknown |
557 lookup, modified, added, unknown, ignored = [], [], [], [], [] |
552 lookup, modified, added, unknown, ignored = [], [], [], [], [] |
558 removed, deleted, clean = [], [], [] |
553 removed, deleted, clean = [], [], [] |