422 return False |
422 return False |
423 badfn = fwarn |
423 badfn = fwarn |
424 if hasattr(match, 'bad'): |
424 if hasattr(match, 'bad'): |
425 badfn = match.bad |
425 badfn = match.bad |
426 |
426 |
427 files = util.unique(match.files()) |
|
428 if not files or '.' in files: |
|
429 files = [''] |
|
430 dmap = self._map |
|
431 |
|
432 def imatch(file_): |
|
433 if file_ not in dmap and self._ignore(file_): |
|
434 return False |
|
435 return match(file_) |
|
436 |
|
437 def badtype(f, mode): |
427 def badtype(f, mode): |
438 kind = 'unknown' |
428 kind = 'unknown' |
439 if stat.S_ISCHR(mode): kind = _('character device') |
429 if stat.S_ISCHR(mode): kind = _('character device') |
440 elif stat.S_ISBLK(mode): kind = _('block device') |
430 elif stat.S_ISBLK(mode): kind = _('block device') |
441 elif stat.S_ISFIFO(mode): kind = _('fifo') |
431 elif stat.S_ISFIFO(mode): kind = _('fifo') |
442 elif stat.S_ISSOCK(mode): kind = _('socket') |
432 elif stat.S_ISSOCK(mode): kind = _('socket') |
443 elif stat.S_ISDIR(mode): kind = _('directory') |
433 elif stat.S_ISDIR(mode): kind = _('directory') |
444 self._ui.warn(_('%s: unsupported file type (type is %s)\n') |
434 self._ui.warn(_('%s: unsupported file type (type is %s)\n') |
445 % (self.pathto(f), kind)) |
435 % (self.pathto(f), kind)) |
446 |
436 |
|
437 def imatch(f): |
|
438 return (f in dmap or not ignore(f)) and match(f) |
|
439 |
447 # TODO: don't walk unknown directories if unknown and ignored are False |
440 # TODO: don't walk unknown directories if unknown and ignored are False |
448 ignore = self._ignore |
441 ignore = self._ignore |
449 dirignore = self._dirignore |
442 dirignore = self._dirignore |
450 if ignored: |
443 if ignored: |
451 imatch = match |
444 imatch = match |
452 ignore = util.never |
445 ignore = util.never |
453 dirignore = util.never |
446 dirignore = util.never |
454 |
447 |
|
448 dmap = self._map |
455 normpath = util.normpath |
449 normpath = util.normpath |
456 normalize = self.normalize |
450 normalize = self.normalize |
457 listdir = osutil.listdir |
451 listdir = osutil.listdir |
458 lstat = os.lstat |
452 lstat = os.lstat |
459 bisect_left = bisect.bisect_left |
453 bisect_left = bisect.bisect_left |
460 pconvert = util.pconvert |
454 pconvert = util.pconvert |
461 join = os.path.join |
|
462 getkind = stat.S_IFMT |
455 getkind = stat.S_IFMT |
463 dirkind = stat.S_IFDIR |
456 dirkind = stat.S_IFDIR |
464 regkind = stat.S_IFREG |
457 regkind = stat.S_IFREG |
465 lnkkind = stat.S_IFLNK |
458 lnkkind = stat.S_IFLNK |
466 _join = self._join |
459 join = self._join |
467 work = [] |
460 work = [] |
468 wadd = work.append |
461 wadd = work.append |
469 |
462 |
470 results = {} |
463 files = util.unique(match.files()) |
|
464 if not files or '.' in files: |
|
465 files = [''] |
|
466 results = {'.hg': None} |
471 |
467 |
472 # step 1: find all explicit files |
468 # step 1: find all explicit files |
473 for ff in util.sort(files): |
469 for ff in util.sort(files): |
474 nf = normalize(normpath(ff)) |
470 nf = normalize(normpath(ff)) |
475 if nf in results: |
471 if nf in results: |
476 continue |
472 continue |
477 |
473 |
478 try: |
474 try: |
479 st = lstat(_join(nf)) |
475 st = lstat(join(nf)) |
480 kind = getkind(st.st_mode) |
476 kind = getkind(st.st_mode) |
481 if kind == dirkind: |
477 if kind == dirkind: |
482 if not dirignore(nf): |
478 if not dirignore(nf): |
483 wadd(nf) |
479 wadd(nf) |
484 elif kind == regkind or kind == lnkkind: |
480 elif kind == regkind or kind == lnkkind: |
503 # step 2: visit subdirectories |
499 # step 2: visit subdirectories |
504 while work: |
500 while work: |
505 nd = work.pop() |
501 nd = work.pop() |
506 if hasattr(match, 'dir'): |
502 if hasattr(match, 'dir'): |
507 match.dir(nd) |
503 match.dir(nd) |
508 entries = listdir(_join(nd), stat=True) |
504 entries = listdir(join(nd), stat=True) |
509 if nd == '.': |
505 if nd == '.': |
510 nd = '' |
506 nd = '' |
511 elif nd == '.hg': |
|
512 continue |
|
513 else: |
507 else: |
514 # do not recurse into a repo contained in this |
508 # do not recurse into a repo contained in this |
515 # one. use bisect to find .hg directory so speed |
509 # one. use bisect to find .hg directory so speed |
516 # is good on big directory. |
510 # is good on big directory. |
517 hg = bisect_left(entries, ('.hg')) |
511 hg = bisect_left(entries, ('.hg')) |
531 results[nf] = st |
525 results[nf] = st |
532 elif nf in dmap: |
526 elif nf in dmap: |
533 results[nf] = None |
527 results[nf] = None |
534 |
528 |
535 # step 3: report unseen items in the dmap hash |
529 # step 3: report unseen items in the dmap hash |
536 for f in util.sort(dmap): |
530 for nf in util.sort(dmap): |
537 if f not in results and match(f): |
531 if nf not in results and match(nf): |
538 results[f] = None |
532 results[nf] = None |
539 try: |
533 try: |
540 st = lstat(_join(f)) |
534 st = lstat(join(nf)) |
541 kind = getkind(st.st_mode) |
535 kind = getkind(st.st_mode) |
542 if kind == regkind or kind == lnkkind: |
536 if kind == regkind or kind == lnkkind: |
543 results[f] = st |
537 results[nf] = st |
544 except OSError, inst: |
538 except OSError, inst: |
545 if inst.errno not in (errno.ENOENT, errno.ENOTDIR): |
539 if inst.errno not in (errno.ENOENT, errno.ENOTDIR): |
546 raise |
540 raise |
547 |
541 |
|
542 del results['.hg'] |
548 return results |
543 return results |
549 |
544 |
550 def status(self, match, ignored, clean, unknown): |
545 def status(self, match, ignored, clean, unknown): |
551 listignored, listclean, listunknown = ignored, clean, unknown |
546 listignored, listclean, listunknown = ignored, clean, unknown |
552 lookup, modified, added, unknown, ignored = [], [], [], [], [] |
547 lookup, modified, added, unknown, ignored = [], [], [], [], [] |