runstatus: do not recurse into subdirectories if not needed

This speeds up the case when you run git-status, having an untracked
subdirectory containing huge amounts of files.

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
Johannes Schindelin 2006-09-28 02:44:30 +02:00 committed by Junio C Hamano
parent a3f5d02edb
commit 07ccbff89b

27
dir.c
View File

@ -283,7 +283,7 @@ static int dir_exists(const char *dirname, int len)
* Also, we ignore the name ".git" (even if it is not a directory). * Also, we ignore the name ".git" (even if it is not a directory).
* That likely will not change. * That likely will not change.
*/ */
static int read_directory_recursive(struct dir_struct *dir, const char *path, const char *base, int baselen) static int read_directory_recursive(struct dir_struct *dir, const char *path, const char *base, int baselen, int check_only)
{ {
DIR *fdir = opendir(path); DIR *fdir = opendir(path);
int contents = 0; int contents = 0;
@ -314,7 +314,6 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co
switch (DTYPE(de)) { switch (DTYPE(de)) {
struct stat st; struct stat st;
int subdir, rewind_base;
default: default:
continue; continue;
case DT_UNKNOWN: case DT_UNKNOWN:
@ -328,26 +327,30 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co
case DT_DIR: case DT_DIR:
memcpy(fullname + baselen + len, "/", 2); memcpy(fullname + baselen + len, "/", 2);
len++; len++;
rewind_base = dir->nr;
subdir = read_directory_recursive(dir, fullname, fullname,
baselen + len);
if (dir->show_other_directories && if (dir->show_other_directories &&
(subdir || !dir->hide_empty_directories) &&
!dir_exists(fullname, baselen + len)) { !dir_exists(fullname, baselen + len)) {
/* Rewind the read subdirectory */ if (dir->hide_empty_directories &&
while (dir->nr > rewind_base) !read_directory_recursive(dir,
free(dir->entries[--dir->nr]); fullname, fullname,
baselen + len, 1))
continue;
break; break;
} }
contents += subdir;
contents += read_directory_recursive(dir,
fullname, fullname, baselen + len, 0);
continue; continue;
case DT_REG: case DT_REG:
case DT_LNK: case DT_LNK:
break; break;
} }
add_name(dir, fullname, baselen + len);
contents++; contents++;
if (check_only)
goto exit_early;
else
add_name(dir, fullname, baselen + len);
} }
exit_early:
closedir(fdir); closedir(fdir);
pop_exclude_per_directory(dir, exclude_stk); pop_exclude_per_directory(dir, exclude_stk);
@ -393,7 +396,7 @@ int read_directory(struct dir_struct *dir, const char *path, const char *base, i
} }
} }
read_directory_recursive(dir, path, base, baselen); read_directory_recursive(dir, path, base, baselen, 0);
qsort(dir->entries, dir->nr, sizeof(struct dir_entry *), cmp_name); qsort(dir->entries, dir->nr, sizeof(struct dir_entry *), cmp_name);
return dir->nr; return dir->nr;
} }