mirror of
https://github.com/git/git
synced 2024-08-24 18:26:02 +00:00
dir.c: refactor is_path_excluded()
In a similar way to the previous commit, this extracts a new helper function last_exclude_matching_path() which return the last exclude_list element which matched, or NULL if no match was found. is_path_excluded() becomes a wrapper around this, and just returns 0 or 1 depending on whether any matching exclude_list element was found. This allows callers to find out _why_ a given path was excluded, rather than just whether it was or not, paving the way for a new git sub-command which allows users to test their exclude lists from the command line. Signed-off-by: Adam Spiers <git@adamspiers.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
f4cd69a674
commit
a35341a86e
47
dir.c
47
dir.c
|
@ -709,6 +709,7 @@ void path_exclude_check_init(struct path_exclude_check *check,
|
||||||
struct dir_struct *dir)
|
struct dir_struct *dir)
|
||||||
{
|
{
|
||||||
check->dir = dir;
|
check->dir = dir;
|
||||||
|
check->exclude = NULL;
|
||||||
strbuf_init(&check->path, 256);
|
strbuf_init(&check->path, 256);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -718,18 +719,21 @@ void path_exclude_check_clear(struct path_exclude_check *check)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Is this name excluded? This is for a caller like show_files() that
|
* For each subdirectory in name, starting with the top-most, checks
|
||||||
* do not honor directory hierarchy and iterate through paths that are
|
* to see if that subdirectory is excluded, and if so, returns the
|
||||||
* possibly in an ignored directory.
|
* corresponding exclude structure. Otherwise, checks whether name
|
||||||
|
* itself (which is presumably a file) is excluded.
|
||||||
*
|
*
|
||||||
* A path to a directory known to be excluded is left in check->path to
|
* A path to a directory known to be excluded is left in check->path to
|
||||||
* optimize for repeated checks for files in the same excluded directory.
|
* optimize for repeated checks for files in the same excluded directory.
|
||||||
*/
|
*/
|
||||||
int is_path_excluded(struct path_exclude_check *check,
|
struct exclude *last_exclude_matching_path(struct path_exclude_check *check,
|
||||||
const char *name, int namelen, int *dtype)
|
const char *name, int namelen,
|
||||||
|
int *dtype)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct strbuf *path = &check->path;
|
struct strbuf *path = &check->path;
|
||||||
|
struct exclude *exclude;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* we allow the caller to pass namelen as an optimization; it
|
* we allow the caller to pass namelen as an optimization; it
|
||||||
|
@ -739,11 +743,17 @@ int is_path_excluded(struct path_exclude_check *check,
|
||||||
if (namelen < 0)
|
if (namelen < 0)
|
||||||
namelen = strlen(name);
|
namelen = strlen(name);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If path is non-empty, and name is equal to path or a
|
||||||
|
* subdirectory of path, name should be excluded, because
|
||||||
|
* it's inside a directory which is already known to be
|
||||||
|
* excluded and was previously left in check->path.
|
||||||
|
*/
|
||||||
if (path->len &&
|
if (path->len &&
|
||||||
path->len <= namelen &&
|
path->len <= namelen &&
|
||||||
!memcmp(name, path->buf, path->len) &&
|
!memcmp(name, path->buf, path->len) &&
|
||||||
(!name[path->len] || name[path->len] == '/'))
|
(!name[path->len] || name[path->len] == '/'))
|
||||||
return 1;
|
return check->exclude;
|
||||||
|
|
||||||
strbuf_setlen(path, 0);
|
strbuf_setlen(path, 0);
|
||||||
for (i = 0; name[i]; i++) {
|
for (i = 0; name[i]; i++) {
|
||||||
|
@ -751,8 +761,12 @@ int is_path_excluded(struct path_exclude_check *check,
|
||||||
|
|
||||||
if (ch == '/') {
|
if (ch == '/') {
|
||||||
int dt = DT_DIR;
|
int dt = DT_DIR;
|
||||||
if (is_excluded(check->dir, path->buf, &dt))
|
exclude = last_exclude_matching(check->dir,
|
||||||
return 1;
|
path->buf, &dt);
|
||||||
|
if (exclude) {
|
||||||
|
check->exclude = exclude;
|
||||||
|
return exclude;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
strbuf_addch(path, ch);
|
strbuf_addch(path, ch);
|
||||||
}
|
}
|
||||||
|
@ -760,7 +774,22 @@ int is_path_excluded(struct path_exclude_check *check,
|
||||||
/* An entry in the index; cannot be a directory with subentries */
|
/* An entry in the index; cannot be a directory with subentries */
|
||||||
strbuf_setlen(path, 0);
|
strbuf_setlen(path, 0);
|
||||||
|
|
||||||
return is_excluded(check->dir, name, dtype);
|
return last_exclude_matching(check->dir, name, dtype);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Is this name excluded? This is for a caller like show_files() that
|
||||||
|
* do not honor directory hierarchy and iterate through paths that are
|
||||||
|
* possibly in an ignored directory.
|
||||||
|
*/
|
||||||
|
int is_path_excluded(struct path_exclude_check *check,
|
||||||
|
const char *name, int namelen, int *dtype)
|
||||||
|
{
|
||||||
|
struct exclude *exclude =
|
||||||
|
last_exclude_matching_path(check, name, namelen, dtype);
|
||||||
|
if (exclude)
|
||||||
|
return exclude->flags & EXC_FLAG_NEGATIVE ? 0 : 1;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct dir_entry *dir_entry_new(const char *pathname, int len)
|
static struct dir_entry *dir_entry_new(const char *pathname, int len)
|
||||||
|
|
3
dir.h
3
dir.h
|
@ -119,10 +119,13 @@ extern int match_pathname(const char *, int,
|
||||||
*/
|
*/
|
||||||
struct path_exclude_check {
|
struct path_exclude_check {
|
||||||
struct dir_struct *dir;
|
struct dir_struct *dir;
|
||||||
|
struct exclude *exclude;
|
||||||
struct strbuf path;
|
struct strbuf path;
|
||||||
};
|
};
|
||||||
extern void path_exclude_check_init(struct path_exclude_check *, struct dir_struct *);
|
extern void path_exclude_check_init(struct path_exclude_check *, struct dir_struct *);
|
||||||
extern void path_exclude_check_clear(struct path_exclude_check *);
|
extern void path_exclude_check_clear(struct path_exclude_check *);
|
||||||
|
extern struct exclude *last_exclude_matching_path(struct path_exclude_check *, const char *,
|
||||||
|
int namelen, int *dtype);
|
||||||
extern int is_path_excluded(struct path_exclude_check *, const char *, int namelen, int *dtype);
|
extern int is_path_excluded(struct path_exclude_check *, const char *, int namelen, int *dtype);
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue