return 0;
}
+static int get_dtype(struct dirent *de, const char *path)
+{
+ int dtype = DTYPE(de);
+ struct stat st;
+
+ if (dtype != DT_UNKNOWN)
+ return dtype;
+ if (lstat(path, &st))
+ return dtype;
+ if (S_ISREG(st.st_mode))
+ return DT_REG;
+ if (S_ISDIR(st.st_mode))
+ return DT_DIR;
+ if (S_ISLNK(st.st_mode))
+ return DT_LNK;
+ return dtype;
+}
+
/*
* Read a directory tree. We currently ignore anything but
* directories, regular files and symlinks. That's because git
exclude_stk = push_exclude_per_directory(dir, base, baselen);
while ((de = readdir(fdir)) != NULL) {
- int len;
+ int len, dtype;
int exclude;
if ((de->d_name[0] == '.') &&
if (exclude && dir->collect_ignored
&& in_pathspec(fullname, baselen + len, simplify))
dir_add_ignored(dir, fullname, baselen + len);
- if (exclude != dir->show_ignored) {
- if (!dir->show_ignored || DTYPE(de) != DT_DIR) {
+
+ /*
+ * Excluded? If we don't explicitly want to show
+ * ignored files, ignore it
+ */
+ if (exclude && !dir->show_ignored)
+ continue;
+
+ dtype = get_dtype(de, fullname);
+
+ /*
+ * Do we want to see just the ignored files?
+ * We still need to recurse into directories,
+ * even if we don't ignore them, since the
+ * directory may contain files that we do..
+ */
+ if (!exclude && dir->show_ignored) {
+ if (dtype != DT_DIR)
continue;
- }
}
- switch (DTYPE(de)) {
- struct stat st;
+ switch (dtype) {
default:
continue;
- case DT_UNKNOWN:
- if (lstat(fullname, &st))
- continue;
- if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode))
- break;
- if (!S_ISDIR(st.st_mode))
- continue;
- /* fallthrough */
case DT_DIR:
memcpy(fullname + baselen + len, "/", 2);
len++;
int read_directory(struct dir_struct *dir, const char *path, const char *base, int baselen, const char **pathspec)
{
struct path_simplify *simplify = create_simplify(pathspec);
+ char *pp = NULL;
/*
* Make sure to do the per-directory exclude for all the
*/
if (baselen) {
if (dir->exclude_per_dir) {
- char *p, *pp = xmalloc(baselen+1);
+ char *p;
+ pp = xmalloc(baselen+1);
memcpy(pp, base, baselen+1);
p = pp;
while (1) {
else
p = pp + baselen;
}
- free(pp);
}
}
read_directory_recursive(dir, path, base, baselen, 0, simplify);
free_simplify(simplify);
+ free(pp);
qsort(dir->entries, dir->nr, sizeof(struct dir_entry *), cmp_name);
qsort(dir->ignored, dir->ignored_nr, sizeof(struct dir_entry *), cmp_name);
return dir->nr;
char buffer[PATH_MAX];
return get_relative_cwd(buffer, sizeof(buffer), dir) != NULL;
}
+
+void setup_standard_excludes(struct dir_struct *dir)
+{
+ const char *path;
+
+ dir->exclude_per_dir = ".gitignore";
+ path = git_path("info/exclude");
+ if (!access(path, R_OK))
+ add_excludes_from_file(dir, path);
+ if (excludes_file && !access(excludes_file, R_OK))
+ add_excludes_from_file(dir, excludes_file);
+}