Add 'fill_directory()' helper function for directory traversal
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 14 May 2009 20:22:36 +0000 (13:22 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 9 Jul 2009 08:11:26 +0000 (01:11 -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.

This also makes the 'common_prefix()' helper function private to dir.c,
since all callers are now in that file.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin-add.c
builtin-clean.c
builtin-ls-files.c
dir.c
dir.h
wt-status.c

index 78989dad8cb07dee00054c3ea98d16eb493a05c9..581a2a17480cc0ffa47a942ff58da4499aeac41d 100644 (file)
@@ -97,35 +97,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;
@@ -343,9 +314,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);
index 1c1b6d26e9987800d2a414e49e4f371a4277b96e..2d8c735d4881a005e4aa5006d9781b71631bb0af 100644 (file)
@@ -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;
@@ -78,16 +77,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);
index 2312866605c4140ac4e5a9f5bb963ca5ab5c6da3..f473220502027b4f9e6ed9a17ffafd42538add80 100644 (file)
@@ -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 74b3bbf6fd557943e0e7b9027556312203e58d7a..0c8553b27c80ca649fa5b8c864583fb75be6fabe 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -19,7 +19,7 @@ static int read_directory_recursive(struct dir_struct *dir,
        int check_only, const struct path_simplify *simplify);
 static int get_dtype(struct dirent *de, const char *path);
 
-int common_prefix(const char **pathspec)
+static int common_prefix(const char **pathspec)
 {
        const char *path, *slash, *next;
        int prefix;
@@ -52,6 +52,27 @@ int common_prefix(const char **pathspec)
        return prefix;
 }
 
+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;
+}
+
 /*
  * Does 'match' match the given name?
  * A match is found if
diff --git a/dir.h b/dir.h
index 541286ad1daeb66a9963288d275534ee963bd5cd..f9d69dd15f3b47e779e70cf0b1f8b38dbd4c74c4 100644 (file)
--- a/dir.h
+++ b/dir.h
@@ -61,13 +61,12 @@ struct dir_struct {
        char basebuf[PATH_MAX];
 };
 
-extern int common_prefix(const char **pathspec);
-
 #define MATCHED_RECURSIVELY 1
 #define MATCHED_FNMATCH 2
 #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 *);
index 0ca4b13c29ee6a8cebc1db4ec59f543aef299484..47735d8129fd3632b85d54b451e30752f251a949 100644 (file)
@@ -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))