diff options
author | Junio C Hamano <gitster@pobox.com> | 2012-06-01 11:28:00 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2012-06-03 16:05:42 -0700 |
commit | eb41775ecc031cd8e38aebbd26826d74922a0db9 (patch) | |
tree | 372293cf02d91d2cf953621d35b367c34b1c18a4 /dir.c | |
parent | d9f5ef7a4a760d58f1f824f9fb8c12ef0371d3a9 (diff) | |
download | git-eb41775ecc031cd8e38aebbd26826d74922a0db9.tar.gz |
ls-files -i: pay attention to exclusion of leading paths
"git ls-files --exclude=t/ -i" does not show paths in directory t/
that have been added to the index, but it should.
The excluded() API was designed for callers who walk the tree from
the top, checking each level of the directory hierarchy as it
descends if it is excluded, and not even bothering to recurse into
an excluded directory. This would allow us optimize for a common
case by not having to check if the exclude pattern "foo/" matches
when looking at "foo/bar", because the caller should have noticed
that "foo" is excluded and did not even bother to read "foo/bar"
out of opendir()/readdir() to call it.
The code for "ls-files -i" however walks the index linearly, feeding
paths without checking if the leading directory is already excluded.
Introduce a helper function path_excluded() to let this caller
properly call excluded() check for higher hierarchies as necessary.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'dir.c')
-rw-r--r-- | dir.c | 32 |
1 files changed, 32 insertions, 0 deletions
@@ -580,6 +580,38 @@ int excluded(struct dir_struct *dir, const char *pathname, int *dtype_p) return 0; } +void path_exclude_check_init(struct path_exclude_check *check, + struct dir_struct *dir) +{ + check->dir = dir; + strbuf_init(&check->path, 256); +} + +void path_exclude_check_clear(struct path_exclude_check *check) +{ + strbuf_release(&check->path); +} + +int path_excluded(struct path_exclude_check *check, struct cache_entry *ce) +{ + int i, dtype; + struct strbuf *path = &check->path; + + strbuf_setlen(path, 0); + for (i = 0; ce->name[i]; i++) { + int ch = ce->name[i]; + + if (ch == '/') { + dtype = DT_DIR; + if (excluded(check->dir, path->buf, &dtype)) + return 1; + } + strbuf_addch(path, ch); + } + dtype = ce_to_dtype(ce); + return excluded(check->dir, ce->name, &dtype); +} + static struct dir_entry *dir_entry_new(const char *pathname, int len) { struct dir_entry *ent; |