comparison mercurial/dirstate.py @ 5001: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
5000:54ff1bb4b53a 5001: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