comparison mercurial/dirstate.py @ 3560:09d99b7e4da0

simplify dirstate walking - kill walkhelper - stop passing dc around - remove unused stat arg from statmatch (renamed imatch)
author Matt Mackall <mpm@selenic.com>
date Thu, 26 Oct 2006 23:54:24 -0500
parents 53e843840349
children 26b556c1d01d
comparison
equal deleted inserted replaced
3559:39011927fdb0 3560:09d99b7e4da0
348 self.ui.warn(_('%s: unsupported file type (type is %s)\n') % ( 348 self.ui.warn(_('%s: unsupported file type (type is %s)\n') % (
349 util.pathto(self.getcwd(), f), 349 util.pathto(self.getcwd(), f),
350 kind)) 350 kind))
351 return False 351 return False
352 352
353 def statwalk(self, files=None, match=util.always, dc=None, ignored=False, 353 def walk(self, files=None, match=util.always, badmatch=None):
354 # filter out the stat
355 for src, f, st in self.statwalk(files, match, badmatch=badmatch):
356 yield src, f
357
358 def statwalk(self, files=None, match=util.always, ignored=False,
354 badmatch=None): 359 badmatch=None):
360 '''
361 walk recursively through the directory tree, finding all files
362 matched by the match function
363
364 results are yielded in a tuple (src, filename, st), where src
365 is one of:
366 'f' the file was found in the directory tree
367 'm' the file was only in the dirstate and not in the tree
368 and st is the stat result if the file was found in the directory.
369 '''
355 self.lazyread() 370 self.lazyread()
356 371
357 # walk all files by default 372 # walk all files by default
358 if not files: 373 if not files:
359 files = [self.root] 374 files = [self.root]
360 if not dc: 375 dc = self.map.copy()
361 dc = self.map.copy() 376 else:
362 elif not dc:
363 dc = self.filterfiles(files) 377 dc = self.filterfiles(files)
364 378
365 def statmatch(file_, stat): 379 def imatch(file_):
366 file_ = util.pconvert(file_) 380 file_ = util.pconvert(file_)
367 if not ignored and file_ not in dc and self.ignore(file_): 381 if not ignored and file_ not in dc and self.ignore(file_):
368 return False 382 return False
369 return match(file_) 383 return match(file_)
370 384
371 return self.walkhelper(files=files, statmatch=statmatch, dc=dc,
372 badmatch=badmatch)
373
374 def walk(self, files=None, match=util.always, dc=None, badmatch=None):
375 # filter out the stat
376 for src, f, st in self.statwalk(files, match, dc, badmatch=badmatch):
377 yield src, f
378
379 # walk recursively through the directory tree, finding all files
380 # matched by the statmatch function
381 #
382 # results are yielded in a tuple (src, filename, st), where src
383 # is one of:
384 # 'f' the file was found in the directory tree
385 # 'm' the file was only in the dirstate and not in the tree
386 # and st is the stat result if the file was found in the directory.
387 #
388 # dc is an optional arg for the current dirstate. dc is not modified
389 # directly by this function, but might be modified by your statmatch call.
390 #
391 def walkhelper(self, files, statmatch, dc, badmatch=None):
392 # self.root may end with a path separator when self.root == '/' 385 # self.root may end with a path separator when self.root == '/'
393 common_prefix_len = len(self.root) 386 common_prefix_len = len(self.root)
394 if not self.root.endswith('/'): 387 if not self.root.endswith('/'):
395 common_prefix_len += 1 388 common_prefix_len += 1
396 # recursion free walker, faster than os.walk. 389 # recursion free walker, faster than os.walk.
419 p = os.path.join(top, f) 412 p = os.path.join(top, f)
420 # don't trip over symlinks 413 # don't trip over symlinks
421 st = os.lstat(p) 414 st = os.lstat(p)
422 if stat.S_ISDIR(st.st_mode): 415 if stat.S_ISDIR(st.st_mode):
423 ds = os.path.join(nd, f +'/') 416 ds = os.path.join(nd, f +'/')
424 if statmatch(ds, st): 417 if imatch(ds):
425 work.append(p) 418 work.append(p)
426 if statmatch(np, st) and np in dc: 419 if imatch(np) and np in dc:
427 yield 'm', np, st 420 yield 'm', np, st
428 elif statmatch(np, st): 421 elif imatch(np):
429 if self.supported_type(np, st): 422 if self.supported_type(np, st):
430 yield 'f', np, st 423 yield 'f', np, st
431 elif np in dc: 424 elif np in dc:
432 yield 'm', np, st 425 yield 'm', np, st
433 426
452 if not found: 445 if not found:
453 if inst.errno != errno.ENOENT or not badmatch: 446 if inst.errno != errno.ENOENT or not badmatch:
454 self.ui.warn('%s: %s\n' % ( 447 self.ui.warn('%s: %s\n' % (
455 util.pathto(self.getcwd(), ff), 448 util.pathto(self.getcwd(), ff),
456 inst.strerror)) 449 inst.strerror))
457 elif badmatch and badmatch(ff) and statmatch(ff, None): 450 elif badmatch and badmatch(ff) and imatch(ff):
458 yield 'b', ff, None 451 yield 'b', ff, None
459 continue 452 continue
460 if stat.S_ISDIR(st.st_mode): 453 if stat.S_ISDIR(st.st_mode):
461 cmp1 = (lambda x, y: cmp(x[1], y[1])) 454 cmp1 = (lambda x, y: cmp(x[1], y[1]))
462 sorted_ = [ x for x in findfiles(f) ] 455 sorted_ = [ x for x in findfiles(f) ]
466 else: 459 else:
467 ff = util.normpath(ff) 460 ff = util.normpath(ff)
468 if seen(ff): 461 if seen(ff):
469 continue 462 continue
470 self.blockignore = True 463 self.blockignore = True
471 if statmatch(ff, st): 464 if imatch(ff):
472 if self.supported_type(ff, st, verbose=True): 465 if self.supported_type(ff, st, verbose=True):
473 yield 'f', ff, st 466 yield 'f', ff, st
474 elif ff in dc: 467 elif ff in dc:
475 yield 'm', ff, st 468 yield 'm', ff, st
476 self.blockignore = False 469 self.blockignore = False
478 # step two run through anything left in the dc hash and yield 471 # step two run through anything left in the dc hash and yield
479 # if we haven't already seen it 472 # if we haven't already seen it
480 ks = dc.keys() 473 ks = dc.keys()
481 ks.sort() 474 ks.sort()
482 for k in ks: 475 for k in ks:
483 if not seen(k) and (statmatch(k, None)): 476 if not seen(k) and imatch(k):
484 yield 'm', k, None 477 yield 'm', k, None
485 478
486 def status(self, files=None, match=util.always, list_ignored=False, 479 def status(self, files=None, match=util.always, list_ignored=False,
487 list_clean=False): 480 list_clean=False):
488 lookup, modified, added, unknown, ignored = [], [], [], [], [] 481 lookup, modified, added, unknown, ignored = [], [], [], [], []