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@xxxxxx> --- On Thu, 28 Sep 2006, Johannes Schindelin wrote: > On Wed, 27 Sep 2006, Junio C Hamano wrote: > > > Does this really check if the directory is empty (I think you > > would read "." and ".." out of it at least)? > > > > When the original code recurses into subdirectory, it seems to > > behave identically for a truly empty directory and a directory > > that has only ".git" (or excluded files in it under > > !show_ignored). > > Of course I missed that. Probably, because there is no test for > that. > > [...] > > Now, I could enhance dir_is_empty() to recursively test if the > dir is empty, and return 0 on first sight of a not-excluded dir > entry, but is it really worth the hassle? Okay, so no more dir_is_empty(). Instead, read_directory_recursive() gets a flag. With this flag, "check_only", it exits as soon as it found valid entries, but does not add any. Way easier. dir.c | 27 +++++++++++++++------------ 1 files changed, 15 insertions(+), 12 deletions(-) diff --git a/dir.c b/dir.c index e2f472b..96389b3 100644 --- a/dir.c +++ b/dir.c @@ -283,7 +283,7 @@ static int dir_exists(const char *dirnam * Also, we ignore the name ".git" (even if it is not a directory). * 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); int contents = 0; @@ -314,7 +314,6 @@ static int read_directory_recursive(stru switch (DTYPE(de)) { struct stat st; - int subdir, rewind_base; default: continue; case DT_UNKNOWN: @@ -328,26 +327,30 @@ static int read_directory_recursive(stru case DT_DIR: memcpy(fullname + baselen + len, "/", 2); len++; - rewind_base = dir->nr; - subdir = read_directory_recursive(dir, fullname, fullname, - baselen + len); if (dir->show_other_directories && - (subdir || !dir->hide_empty_directories) && !dir_exists(fullname, baselen + len)) { - /* Rewind the read subdirectory */ - while (dir->nr > rewind_base) - free(dir->entries[--dir->nr]); + if (dir->hide_empty_directories && + !read_directory_recursive(dir, + fullname, fullname, + baselen + len, 1)) + continue; break; } - contents += subdir; + + contents += read_directory_recursive(dir, + fullname, fullname, baselen + len, 0); continue; case DT_REG: case DT_LNK: break; } - add_name(dir, fullname, baselen + len); contents++; + if (check_only) + goto exit_early; + else + add_name(dir, fullname, baselen + len); } +exit_early: closedir(fdir); pop_exclude_per_directory(dir, exclude_stk); @@ -393,7 +396,7 @@ int read_directory(struct dir_struct *di } } - 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); return dir->nr; } - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html