# HG changeset patch # User Bryan O'Sullivan # Date 1354319707 28800 # Node ID 74912fe3d7187cd945c520182d76ed4a0cbceb63 # Parent a39fe76c4c65c73d8824f7e3092dbbc049235422 dirstate: move file type filtering to its source This prepares us to move to a much faster statfiles implementation on Unix. diff -r a39fe76c4c65 -r 74912fe3d718 mercurial/dirstate.py --- a/mercurial/dirstate.py Mon Oct 08 19:34:04 2012 +0200 +++ b/mercurial/dirstate.py Fri Nov 30 15:55:07 2012 -0800 @@ -697,9 +697,6 @@ if not skipstep3 and not exact: visit = sorted([f for f in dmap if f not in results and matchfn(f)]) for nf, st in zip(visit, util.statfiles([join(i) for i in visit])): - if (not st is None and - getkind(st.st_mode) not in (regkind, lnkkind)): - st = None results[nf] = st for s in subrepos: del results[s] diff -r a39fe76c4c65 -r 74912fe3d718 mercurial/posix.py --- a/mercurial/posix.py Mon Oct 08 19:34:04 2012 +0200 +++ b/mercurial/posix.py Fri Nov 30 15:55:07 2012 -0800 @@ -352,12 +352,18 @@ def setsignalhandler(): pass +_wantedkinds = set([stat.S_IFREG, stat.S_IFLNK]) + def statfiles(files): - 'Stat each file in files and yield stat or None if file does not exist.' + '''Stat each file in files. Yield each stat, or None if a file does not + exist or has a type we don't care about.''' lstat = os.lstat + getkind = stat.S_IFMT for nf in files: try: st = lstat(nf) + if getkind(st.st_mode) not in _wantedkinds: + st = None except OSError, err: if err.errno not in (errno.ENOENT, errno.ENOTDIR): raise diff -r a39fe76c4c65 -r 74912fe3d718 mercurial/windows.py --- a/mercurial/windows.py Mon Oct 08 19:34:04 2012 +0200 +++ b/mercurial/windows.py Fri Nov 30 15:55:07 2012 -0800 @@ -7,7 +7,7 @@ from i18n import _ import osutil, encoding -import errno, msvcrt, os, re, sys, _winreg +import errno, msvcrt, os, re, stat, sys, _winreg import win32 executablepath = win32.executablepath @@ -213,10 +213,15 @@ return executable return findexisting(os.path.expanduser(os.path.expandvars(command))) +_wantedkinds = set([stat.S_IFREG, stat.S_IFLNK]) + def statfiles(files): - '''Stat each file in files and yield stat or None if file does not exist. + '''Stat each file in files. Yield each stat, or None if a file + does not exist or has a type we don't care about. + Cluster and cache stat per directory to minimize number of OS stat calls.''' dircache = {} # dirname -> filename -> status | None if file does not exist + getkind = stat.S_IFMT for nf in files: nf = normcase(nf) dir, base = os.path.split(nf) @@ -226,7 +231,8 @@ if cache is None: try: dmap = dict([(normcase(n), s) - for n, k, s in osutil.listdir(dir, True)]) + for n, k, s in osutil.listdir(dir, True) + if getkind(s) in _wantedkinds]) except OSError, err: # handle directory not found in Python version prior to 2.5 # Python <= 2.4 returns native Windows code 3 in errno