Code

Merge branch 'js/rerere'
[git.git] / dir.c
diff --git a/dir.c b/dir.c
index 5a40d8ff8c99c80bf8f0484425db6022c6f7d8e9..16401d8017c5d96dc17ac9d52ab77eabbc4e9270 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -5,9 +5,6 @@
  * Copyright (C) Linus Torvalds, 2005-2006
  *              Junio Hamano, 2005-2006
  */
-#include <dirent.h>
-#include <fnmatch.h>
-
 #include "cache.h"
 #include "dir.h"
 
@@ -156,7 +153,7 @@ void add_excludes_from_file(struct dir_struct *dir, const char *fname)
                die("cannot use %s as an exclude file", fname);
 }
 
-static int push_exclude_per_directory(struct dir_struct *dir, const char *base, int baselen)
+int push_exclude_per_directory(struct dir_struct *dir, const char *base, int baselen)
 {
        char exclude_file[PATH_MAX];
        struct exclude_list *el = &dir->exclude_list[EXC_DIRS];
@@ -170,7 +167,7 @@ static int push_exclude_per_directory(struct dir_struct *dir, const char *base,
        return current_nr;
 }
 
-static void pop_exclude_per_directory(struct dir_struct *dir, int stk)
+void pop_exclude_per_directory(struct dir_struct *dir, int stk)
 {
        struct exclude_list *el = &dir->exclude_list[EXC_DIRS];
 
@@ -283,7 +280,7 @@ static int dir_exists(const char *dirname, int len)
  * 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 +311,6 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co
 
                        switch (DTYPE(de)) {
                        struct stat st;
-                       int subdir, rewind_base;
                        default:
                                continue;
                        case DT_UNKNOWN:
@@ -328,26 +324,30 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co
                        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 +393,14 @@ 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);
        return dir->nr;
 }
+
+int
+file_exists(const char *f)
+{
+  struct stat sb;
+  return stat(f, &sb) == 0;
+}