Mercurial > hg-stable
comparison mercurial/dirstate.py @ 5000:46facb73ba8b
dirstate: localize a bunch of methods for findfiles
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Thu, 26 Jul 2007 12:02:58 -0500 |
parents | 4106dde15aed |
children | 62e3fd2baca4 |
comparison
equal
deleted
inserted
replaced
4999:54ff1bb4b53a | 5000:46facb73ba8b |
---|---|
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} |
410 known[fn] = 1 | 421 known[fn] = 1 |
411 | 422 |
412 # step one, find all files that match our criteria | 423 # step one, find all files that match our criteria |
413 files.sort() | 424 files.sort() |
414 for ff in files: | 425 for ff in files: |
415 nf = util.normpath(ff) | 426 nf = normpath(ff) |
416 f = self._join(ff) | 427 f = self._join(ff) |
417 try: | 428 try: |
418 st = os.lstat(f) | 429 st = lstat(f) |
419 except OSError, inst: | 430 except OSError, inst: |
420 found = False | 431 found = False |
421 for fn in dc: | 432 for fn in dc: |
422 if nf == fn or (fn.startswith(nf) and fn[len(nf)] == '/'): | 433 if nf == fn or (fn.startswith(nf) and fn[len(nf)] == '/'): |
423 found = True | 434 found = True |
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 |