listdir: add support for aborting if a certain path is found
This lets us bail out early if we find '.hg', letting us skip sorting
and bisecting for it.
--- a/mercurial/dirstate.py Sat Sep 13 10:44:44 2008 -0500
+++ b/mercurial/dirstate.py Sat Sep 13 10:46:47 2008 -0500
@@ -9,7 +9,7 @@
from node import nullid
from i18n import _
-import struct, os, bisect, stat, util, errno, ignore
+import struct, os, stat, util, errno, ignore
import cStringIO, osutil, sys
_unknown = ('?', 0, 0, 0)
@@ -458,7 +458,6 @@
normalize = self.normalize
listdir = osutil.listdir
lstat = os.lstat
- bisect_left = bisect.bisect_left
pconvert = util.pconvert
getkind = stat.S_IFMT
dirkind = stat.S_IFDIR
@@ -510,17 +509,11 @@
nd = work.pop()
if hasattr(match, 'dir'):
match.dir(nd)
- entries = listdir(join(nd), stat=True)
if nd == '.':
nd = ''
+ entries = listdir(join(nd), stat=True)
else:
- # do not recurse into a repo contained in this
- # one. use bisect to find .hg directory so speed
- # is good on big directory.
- hg = bisect_left(entries, ('.hg'))
- if hg < len(entries) and entries[hg][0] == '.hg' \
- and entries[hg][1] == dirkind:
- continue
+ entries = listdir(join(nd), stat=True, skip ='.hg')
for f, kind, st in entries:
nf = normalize(nd and (nd + "/" + f) or f)
if nf not in results:
--- a/mercurial/osutil.c Sat Sep 13 10:44:44 2008 -0500
+++ b/mercurial/osutil.c Sat Sep 13 10:46:47 2008 -0500
@@ -114,17 +114,18 @@
static PyObject *listdir(PyObject *self, PyObject *args, PyObject *kwargs)
{
- static char *kwlist[] = { "path", "stat", NULL };
+ static char *kwlist[] = { "path", "stat", "skip", NULL };
PyObject *statflag = NULL, *list, *elem, *stat, *ret = NULL;
- char fullpath[PATH_MAX + 10], *path;
+ char fullpath[PATH_MAX + 10], *path, *skip = NULL;
int pathlen, keepstat, kind, dfd = -1, err;
struct stat st;
struct dirent *ent;
DIR *dir;
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|O:listdir", kwlist,
- &path, &pathlen, &statflag))
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|Os:listdir", kwlist,
+ &path, &pathlen, &statflag, &skip))
goto error_parse;
+
if (pathlen >= PATH_MAX)
goto error_parse;
@@ -177,6 +178,12 @@
kind = st.st_mode & S_IFMT;
}
+ /* quit early? */
+ if (skip && kind == S_IFDIR && !strcmp(ent->d_name, skip)) {
+ ret = PyList_New(0);
+ goto error;
+ }
+
if (keepstat) {
stat = PyObject_CallObject((PyObject *)&listdir_stat_type, NULL);
if (!stat)
@@ -192,7 +199,6 @@
Py_DECREF(elem);
}
- PyList_Sort(list);
ret = list;
Py_INCREF(ret);
--- a/mercurial/osutil.py Sat Sep 13 10:44:44 2008 -0500
+++ b/mercurial/osutil.py Sat Sep 13 10:46:47 2008 -0500
@@ -10,7 +10,7 @@
if stat.S_ISSOCK(mode): return stat.S_IFSOCK
return mode
-def listdir(path, stat=False):
+def listdir(path, stat=False, skip=None):
'''listdir(path, stat=False) -> list_of_tuples
Return a sorted list containing information about the entries
@@ -30,6 +30,8 @@
names.sort()
for fn in names:
st = os.lstat(prefix + fn)
+ if fn == skip and stat.S_ISDIR(st.st_mode):
+ return []
if stat:
result.append((fn, _mode_to_kind(st.st_mode), st))
else: