struct dir_entry *ent;
ent = xmalloc(sizeof(*ent) + len + 1);
- ent->ignored = ent->ignored_dir = 0;
ent->len = len;
memcpy(ent->name, pathname, len);
ent->name[len] = 0;
if (cache_name_pos(pathname, len) >= 0)
return NULL;
- ALLOC_GROW(dir->entries, dir->nr, dir->alloc);
+ ALLOC_GROW(dir->entries, dir->nr+1, dir->alloc);
return dir->entries[dir->nr++] = dir_entry_new(pathname, len);
}
+struct dir_entry *dir_add_ignored(struct dir_struct *dir, const char *pathname, int len)
+{
+ if (cache_name_pos(pathname, len) >= 0)
+ return NULL;
+
+ ALLOC_GROW(dir->ignored, dir->ignored_nr+1, dir->ignored_alloc);
+ return dir->ignored[dir->ignored_nr++] = dir_entry_new(pathname, len);
+}
+
enum exist_status {
index_nonexistent = 0,
index_directory,
return 0;
}
+static int in_pathspec(const char *path, int len, const struct path_simplify *simplify)
+{
+ if (simplify) {
+ for (; simplify->path; simplify++) {
+ if (len == simplify->len
+ && !memcmp(path, simplify->path, len))
+ return 1;
+ }
+ }
+ return 0;
+}
+
/*
* Read a directory tree. We currently ignore anything but
* directories, regular files and symlinks. That's because git
continue;
exclude = excluded(dir, fullname);
+ 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) {
continue;
read_directory_recursive(dir, path, base, baselen, 0, simplify);
free_simplify(simplify);
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;
}
struct stat sb;
return stat(f, &sb) == 0;
}
+
+/*
+ * get_relative_cwd() gets the prefix of the current working directory
+ * relative to 'dir'. If we are not inside 'dir', it returns NULL.
+ *
+ * As a convenience, it also returns NULL if 'dir' is already NULL. The
+ * reason for this behaviour is that it is natural for functions returning
+ * directory names to return NULL to say "this directory does not exist"
+ * or "this directory is invalid". These cases are usually handled the
+ * same as if the cwd is not inside 'dir' at all, so get_relative_cwd()
+ * returns NULL for both of them.
+ *
+ * Most notably, get_relative_cwd(buffer, size, get_git_work_tree())
+ * unifies the handling of "outside work tree" with "no work tree at all".
+ */
+char *get_relative_cwd(char *buffer, int size, const char *dir)
+{
+ char *cwd = buffer;
+
+ if (!dir)
+ return NULL;
+ if (!getcwd(buffer, size))
+ die("can't find the current directory: %s", strerror(errno));
+
+ if (!is_absolute_path(dir))
+ dir = make_absolute_path(dir);
+
+ while (*dir && *dir == *cwd) {
+ dir++;
+ cwd++;
+ }
+ if (*dir)
+ return NULL;
+ if (*cwd == '/')
+ return cwd + 1;
+ return cwd;
+}
+
+int is_inside_dir(const char *dir)
+{
+ char buffer[PATH_MAX];
+ return get_relative_cwd(buffer, sizeof(buffer), dir) != NULL;
+}