git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 2nd try] runstatus: do not recurse into subdirectories if not needed

From
Johannes Schindelin <johannes.schindelin@gmx.de>
Date
Sep 28, 2006, 00:44 UTC
Message-ID
<Pine.LNX.4.63.0609280240060.14200@wbgn013.biozentrum.uni-wuerzburg.de>
In-Reply-To
<Pine.LNX.4.63.0609280216350.14200@wbgn013.biozentrum.uni-wuerzburg.de>

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>
---
	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;
 }
Previous: Johannes SchindelinNext: Junio C Hamano
Message 4 of 5 in “runstatus: do not recurse into subdirectories if not needed”
  1. runstatus: do not recurse into subdirectories if not neededJohannes Schindelin, Sep 27, 2006
  2. Junio C HamanoSep 28, 2006
  3. Johannes SchindelinSep 28, 2006
  4. runstatus: do not recurse into subdirectories if not neededJohannes Schindelin, Sep 28, 2006
  5. Junio C HamanoSep 28, 2006

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.