From eb41775ecc031cd8e38aebbd26826d74922a0db9 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 1 Jun 2012 11:28:00 -0700 Subject: 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 --- dir.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'dir.h') diff --git a/dir.h b/dir.h index dd6947e1d4..7378e69c17 100644 --- a/dir.h +++ b/dir.h @@ -1,6 +1,8 @@ #ifndef DIR_H #define DIR_H +#include "strbuf.h" + struct dir_entry { unsigned int len; char name[FLEX_ARRAY]; /* more */ @@ -78,6 +80,20 @@ extern int excluded_from_list(const char *pathname, int pathlen, const char *bas int *dtype, struct exclude_list *el); extern int excluded(struct dir_struct *, const char *, int *); struct dir_entry *dir_add_ignored(struct dir_struct *dir, const char *pathname, int len); + +/* + * The excluded() API is meant for callers that check each level of leading + * directory hierarchies with excluded() to avoid recursing into excluded + * directories. Callers that do not do so should use this API instead. + */ +struct path_exclude_check { + struct dir_struct *dir; + struct strbuf path; +}; +extern void path_exclude_check_init(struct path_exclude_check *, struct dir_struct *); +extern void path_exclude_check_clear(struct path_exclude_check *); +extern int path_excluded(struct path_exclude_check *, struct cache_entry *); + extern int add_excludes_from_file_to_list(const char *fname, const char *base, int baselen, char **buf_p, struct exclude_list *which, int check_index); extern void add_excludes_from_file(struct dir_struct *, const char *fname); -- cgit v1.2.1 From 782cd4c0f6e0fef5147cb738009dde6e778f4932 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 5 Jun 2012 21:17:52 -0700 Subject: path_excluded(): update API to less cache-entry centric It was stupid of me to make the API too much cache-entry specific; the caller may want to check arbitrary pathname without having a corresponding cache-entry to see if a path is ignored. Signed-off-by: Junio C Hamano --- dir.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'dir.h') diff --git a/dir.h b/dir.h index 7378e69c17..36a82b3bd1 100644 --- a/dir.h +++ b/dir.h @@ -92,7 +92,8 @@ struct path_exclude_check { }; extern void path_exclude_check_init(struct path_exclude_check *, struct dir_struct *); extern void path_exclude_check_clear(struct path_exclude_check *); -extern int path_excluded(struct path_exclude_check *, struct cache_entry *); +extern int path_excluded(struct path_exclude_check *, const char *, int namelen, int *dtype); + extern int add_excludes_from_file_to_list(const char *fname, const char *base, int baselen, char **buf_p, struct exclude_list *which, int check_index); -- cgit v1.2.1 From 0d316f0ceff1c416c25327f40bc5fbdded98a01a Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 5 Jun 2012 22:26:12 -0700 Subject: dir.c: make excluded() file scope static Now there no longer is external callers of this interface, so we can make it static. Signed-off-by: Junio C Hamano --- dir.h | 1 - 1 file changed, 1 deletion(-) (limited to 'dir.h') diff --git a/dir.h b/dir.h index 36a82b3bd1..1a88a7564d 100644 --- a/dir.h +++ b/dir.h @@ -78,7 +78,6 @@ extern int read_directory(struct dir_struct *, const char *path, int len, const extern int excluded_from_list(const char *pathname, int pathlen, const char *basename, int *dtype, struct exclude_list *el); -extern int excluded(struct dir_struct *, const char *, int *); struct dir_entry *dir_add_ignored(struct dir_struct *dir, const char *pathname, int len); /* -- cgit v1.2.1