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

[PATCH 2/3] Add 'fill_directory()' helper function for directory traversal

From
Linus Torvalds <torvalds@linux-foundation.org>
Date
May 14, 2009, 20:46 UTC
Message-ID
<alpine.LFD.2.01.0905141342520.3343@localhost.localdomain>
In-Reply-To
<alpine.LFD.2.01.0905141341470.3343@localhost.localdomain>
From: Linus Torvalds <torvalds@linux-foundation.org>
Date: Thu, 14 May 2009 13:22:36 -0700

Most of the users of "read_directory()" actually want a much simpler interface than the whole complex (but rather powerful) one.

In fact 'git add' had already largely abstracted out the core interface issues into a private "fill_directory()" function that was largely applicable almost as-is to a number of callers. Yes, 'git add' wants to do some extra work of its own, specific to the add semantics, but we can easily split that out, and use the core as a generic function.

This function does exactly that, and now that much simplified 'fill_directory()' function can be shared with a number of callers, while also ensuring that the rather more complex calling conventions of read_directory() are used by fewer call-sites.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---

As you can see from the diffstat, this removes more lines than it adds, and generally simplifies some calling conventions.

The return value from "fill_directory()" makes little sense for any other user than the builtin-add.c case, and I'm not really proud of it, but it basically allows everybody to share the same general infrastructure.

Note: this depends on the previous one, in that we now use the empty 
string ("") as the "path" argument, and now almost all users of 
read_directory() will pass in the same thing as both "path" and "base". 

That will eventually change, though, if we want to have different encodings.

 builtin-add.c      |   45 ++++++++++++++-------------------------------
 builtin-clean.c    |   12 +-----------
 builtin-ls-files.c |    7 +------
 dir.c              |   21 +++++++++++++++++++++
 dir.h              |    1 +
 wt-status.c        |    2 +-
 6 files changed, 39 insertions(+), 49 deletions(-)
diff --git a/builtin-add.c b/builtin-add.c
index cb67d2c..ba25893 100644
--- a/builtin-add.c
+++ b/builtin-add.c
@@ -95,35 +95,6 @@ static void treat_gitlinks(const char **pathspec)
 	}
 }
 
-static void fill_directory(struct dir_struct *dir, const char **pathspec,
-		int ignored_too)
-{
-	const char *path, *base;
-	int baselen;
-
-	/* Set up the default git porcelain excludes */
-	memset(dir, 0, sizeof(*dir));
-	if (!ignored_too) {
-		dir->flags |= DIR_COLLECT_IGNORED;
-		setup_standard_excludes(dir);
-	}
-
-	/*
-	 * Calculate common prefix for the pathspec, and
-	 * use that to optimize the directory walk
-	 */
-	baselen = common_prefix(pathspec);
-	path = ".";
-	base = "";
-	if (baselen)
-		path = base = xmemdupz(*pathspec, baselen);
-
-	/* Read the directory and prune it */
-	read_directory(dir, path, base, baselen, pathspec);
-	if (pathspec)
-		prune_directory(dir, pathspec, baselen);
-}
-
 static void refresh(int verbose, const char **pathspec)
 {
 	char *seen;
@@ -290,9 +261,21 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 		die("index file corrupt");
 	treat_gitlinks(pathspec);
 
-	if (add_new_files)
+	if (add_new_files) {
+		int baselen;
+
+		/* Set up the default git porcelain excludes */
+		memset(&dir, 0, sizeof(dir));
+		if (!ignored_too) {
+			dir.flags |= DIR_COLLECT_IGNORED;
+			setup_standard_excludes(&dir);
+		}
+
 		/* This picks up the paths that are not tracked */
-		fill_directory(&dir, pathspec, ignored_too);
+		baselen = fill_directory(&dir, pathspec);
+		if (pathspec)
+			prune_directory(&dir, pathspec, baselen);
+	}
 
 	if (refresh_only) {
 		refresh(verbose, pathspec);
diff --git a/builtin-clean.c b/builtin-clean.c
index c5ad33d..febd10f 100644
--- a/builtin-clean.c
+++ b/builtin-clean.c
@@ -33,7 +33,6 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
 	int ignored_only = 0, baselen = 0, config_set = 0, errors = 0;
 	struct strbuf directory = STRBUF_INIT;
 	struct dir_struct dir;
-	const char *path, *base;
 	static const char **pathspec;
 	struct strbuf buf = STRBUF_INIT;
 	const char *qname;
@@ -77,16 +76,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
 	pathspec = get_pathspec(prefix, argv);
 	read_cache();
 
-	/*
-	 * Calculate common prefix for the pathspec, and
-	 * use that to optimize the directory walk
-	 */
-	baselen = common_prefix(pathspec);
-	path = ".";
-	base = "";
-	if (baselen)
-		path = base = xmemdupz(*pathspec, baselen);
-	read_directory(&dir, path, base, baselen, pathspec);
+	fill_directory(&dir, pathspec);
 
 	if (pathspec)
 		seen = xmalloc(argc > 0 ? argc : 1);
diff --git a/builtin-ls-files.c b/builtin-ls-files.c
index da2daf4..a011a42 100644
--- a/builtin-ls-files.c
+++ b/builtin-ls-files.c
@@ -161,12 +161,7 @@ static void show_files(struct dir_struct *dir, const char *prefix)
 
 	/* For cached/deleted files we don't need to even do the readdir */
 	if (show_others || show_killed) {
-		const char *path = ".", *base = "";
-		int baselen = prefix_len;
-
-		if (baselen)
-			path = base = prefix;
-		read_directory(dir, path, base, baselen, pathspec);
+		fill_directory(dir, pathspec);
 		if (show_others)
 			show_other_files(dir);
 		if (show_killed)
diff --git a/dir.c b/dir.c
index 0e6b752..c667d38 100644
--- a/dir.c
+++ b/dir.c
@@ -9,6 +9,27 @@
 #include "dir.h"
 #include "refs.h"
 
+int fill_directory(struct dir_struct *dir, const char **pathspec)
+{
+	const char *path, *base;
+	int baselen;
+
+	/*
+	 * Calculate common prefix for the pathspec, and
+	 * use that to optimize the directory walk
+	 */
+	baselen = common_prefix(pathspec);
+	path = "";
+	base = "";
+
+	if (baselen)
+		path = base = xmemdupz(*pathspec, baselen);
+
+	/* Read the directory and prune it */
+	read_directory(dir, path, base, baselen, pathspec);
+	return baselen;
+}
+
 struct path_simplify {
 	int len;
 	const char *path;
diff --git a/dir.h b/dir.h
index 541286a..9f7c3ba 100644
--- a/dir.h
+++ b/dir.h
@@ -68,6 +68,7 @@ extern int common_prefix(const char **pathspec);
 #define MATCHED_EXACTLY 3
 extern int match_pathspec(const char **pathspec, const char *name, int namelen, int prefix, char *seen);
 
+extern int fill_directory(struct dir_struct *dir, const char **pathspec);
 extern int read_directory(struct dir_struct *, const char *path, const char *base, int baselen, const char **pathspec);
 
 extern int excluded(struct dir_struct *, const char *, int *);
diff --git a/wt-status.c b/wt-status.c
index 1b6df45..24a6abf 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -255,7 +255,7 @@ static void wt_status_print_untracked(struct wt_status *s)
 			DIR_SHOW_OTHER_DIRECTORIES | DIR_HIDE_EMPTY_DIRECTORIES;
 	setup_standard_excludes(&dir);
 
-	read_directory(&dir, ".", "", 0, NULL);
+	fill_directory(&dir, NULL);
 	for(i = 0; i < dir.nr; i++) {
 		struct dir_entry *ent = dir.entries[i];
 		if (!cache_name_is_other(ent->name, ent->len))
-- 
1.6.3.1.11.g97114
Previous: Linus TorvaldsNext: Linus Torvalds
Message 2 of 13 in “dir.c: clean up handling of 'path' parameter in read_directory_recursive()”
  1. 1/3 dir.c: clean up handling of 'path' parameter in read_directory_recursive()Linus Torvalds, May 14, 2009
  2. 2/3 Add 'fill_directory()' helper function for directory traversalLinus Torvalds, May 14, 2009
  3. 3/3 read_directory(): infrastructure for pathname character set conversionLinus Torvalds, May 14, 2009
  4. Linus TorvaldsMay 14, 2009
  5. Johannes SchindelinMay 14, 2009
  6. Aaron CohenMay 14, 2009
  7. Linus TorvaldsMay 14, 2009
  8. Linus TorvaldsMay 14, 2009
  9. 4/3 Introduce 'convert_path_to_git()'Linus Torvalds, May 15, 2009
  10. Junio C HamanoMay 16, 2009
  11. Linus TorvaldsMay 16, 2009
  12. Jens KilianMay 19, 2009
  13. John KoleszarMay 19, 2009

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.