comparison mercurial/dirstate.py @ 6826:eca20fee0728

dirstate.walk: pull directory scanning into top-level loop
author Matt Mackall <mpm@selenic.com>
date Tue, 22 Jul 2008 13:03:18 -0500
parents 177b3186f78a
children c978d6752dbb
comparison
equal deleted inserted replaced
6825:177b3186f78a 6826:eca20fee0728
472 found = [] 472 found = []
473 add = found.append 473 add = found.append
474 474
475 seen = {'.hg': 1} 475 seen = {'.hg': 1}
476 476
477 # step one, find all files that match our criteria 477 # step 1: find all explicit files
478 for ff in util.sort(files): 478 for ff in util.sort(files):
479 nf = normalize(normpath(ff)) 479 nf = normalize(normpath(ff))
480 if nf in seen: 480 if nf in seen:
481 continue 481 continue
482 482
493 fwarn(ff, inst.strerror) 493 fwarn(ff, inst.strerror)
494 elif badfn(ff, inst.strerror) and imatch(nf): 494 elif badfn(ff, inst.strerror) and imatch(nf):
495 yield nf, None 495 yield nf, None
496 continue 496 continue
497 497
498 if not s_isdir(st.st_mode): 498 if s_isdir(st.st_mode):
499 if not dirignore(nf):
500 wadd(nf)
501 else:
499 seen[nf] = 1 502 seen[nf] = 1
500 if supported(ff, st.st_mode, verbose=True): 503 if supported(ff, st.st_mode, verbose=True):
501 yield nf, st 504 yield nf, st
502 elif nf in dmap: 505 elif nf in dmap:
503 yield nf, None 506 yield nf, None
504 continue 507
505 508 # step 2: visit subdirectories
506 if dirignore(nf): 509 while work:
507 continue 510 nd = work.pop()
508 511 if hasattr(match, 'dir'):
509 wadd(nf) 512 match.dir(nd)
510 while work: 513 entries = listdir(_join(nd), stat=True)
511 nd = work.pop() 514 # nd is the top of the repository dir tree
512 if hasattr(match, 'dir'): 515 if nd == '.':
513 match.dir(nd) 516 nd = ''
514 entries = listdir(_join(nd), stat=True) 517 else:
515 # nd is the top of the repository dir tree 518 # do not recurse into a repo contained in this
516 if nd == '.': 519 # one. use bisect to find .hg directory so speed
517 nd = '' 520 # is good on big directory.
518 else: 521 hg = bisect_left(entries, ('.hg'))
519 # do not recurse into a repo contained in this 522 if hg < len(entries) and entries[hg][0] == '.hg' \
520 # one. use bisect to find .hg directory so speed 523 and entries[hg][1] == stat.S_IFDIR:
521 # is good on big directory.
522 hg = bisect_left(entries, ('.hg'))
523 if hg < len(entries) and entries[hg][0] == '.hg' \
524 and entries[hg][1] == stat.S_IFDIR:
525 continue
526 for f, kind, st in entries:
527 nf = normalize(pconvert(join(nd, f)))
528 if nf in seen:
529 continue 524 continue
530 seen[nf] = 1 525 for f, kind, st in entries:
531 # don't trip over symlinks 526 nf = normalize(pconvert(join(nd, f)))
532 if kind == stat.S_IFDIR: 527 if nf in seen:
533 if not ignore(nf): 528 continue
534 wadd(nf) 529 seen[nf] = 1
535 if nf in dmap and match(nf): 530 # don't trip over symlinks
536 add((nf, None)) 531 if kind == stat.S_IFDIR:
537 elif imatch(nf): 532 if not ignore(nf):
538 if supported(nf, st.st_mode): 533 wadd(nf)
539 add((nf, st)) 534 if nf in dmap and match(nf):
540 elif nf in dmap: 535 add((nf, None))
541 add((nf, None)) 536 elif imatch(nf):
542 for e in util.sort(found): 537 if supported(nf, st.st_mode):
543 yield e 538 add((nf, st))
544 539 elif nf in dmap:
545 # step two run through anything left in the dmap hash and yield 540 add((nf, None))
546 # if we haven't already seen it 541 for e in util.sort(found):
542 yield e
543
544 # step 3: report unseen items in the dmap hash
547 for f in util.sort(dmap): 545 for f in util.sort(dmap):
548 if f in seen or not match(f): 546 if f in seen or not match(f):
549 continue 547 continue
550 seen[f] = 1 548 seen[f] = 1
551 try: 549 try: