X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=dir.c;h=b3329f41b2b8830d311f88be59037f7325e2b1e4;hb=e663674722d8a64a208d8c176d5bfc340c04b964;hp=f543f50f42d5bca1a6a6f981e8bb1b3cafd352ea;hpb=27c1dbea3e3a23b3c4b3707dfc9a71c3279ae279;p=git.git diff --git a/dir.c b/dir.c index f543f50f4..b3329f41b 100644 --- a/dir.c +++ b/dir.c @@ -271,27 +271,34 @@ int excluded(struct dir_struct *dir, const char *pathname) return 0; } -struct dir_entry *dir_add_name(struct dir_struct *dir, const char *pathname, int len) -{ +static struct dir_entry *dir_entry_new(const char *pathname, int len) { struct dir_entry *ent; - if (cache_name_pos(pathname, len) >= 0) - return NULL; - - if (dir->nr == dir->alloc) { - int alloc = alloc_nr(dir->alloc); - dir->alloc = alloc; - dir->entries = xrealloc(dir->entries, alloc*sizeof(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; - dir->entries[dir->nr++] = ent; return ent; } +struct dir_entry *dir_add_name(struct dir_struct *dir, const char *pathname, int len) +{ + if (cache_name_pos(pathname, len) >= 0) + return NULL; + + 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, @@ -424,6 +431,18 @@ static int simplify_away(const char *path, int pathlen, const struct path_simpli 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 @@ -464,6 +483,9 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co 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; @@ -610,6 +632,7 @@ int read_directory(struct dir_struct *dir, const char *path, const char *base, i 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; } @@ -619,3 +642,41 @@ file_exists(const char *f) 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. + */ +char *get_relative_cwd(char *buffer, int size, const char *dir) +{ + char *cwd = buffer; + + /* + * a lazy caller can pass a NULL returned from get_git_work_tree() + * and rely on this function to return NULL. + */ + 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; +}