Skip to content

Commit a35341a

Browse files
aspiersgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent f4cd69a commit a35341a

File tree

2 files changed

+41
-9
lines changed

2 files changed

+41
-9
lines changed

dir.c

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,7 @@ void path_exclude_check_init(struct path_exclude_check *check,
709709
struct dir_struct *dir)
710710
{
711711
check->dir = dir;
712+
check->exclude = NULL;
712713
strbuf_init(&check->path, 256);
713714
}
714715

@@ -718,18 +719,21 @@ void path_exclude_check_clear(struct path_exclude_check *check)
718719
}
719720

720721
/*
721-
* Is this name excluded? This is for a caller like show_files() that
722-
* do not honor directory hierarchy and iterate through paths that are
723-
* possibly in an ignored directory.
722+
* For each subdirectory in name, starting with the top-most, checks
723+
* to see if that subdirectory is excluded, and if so, returns the
724+
* corresponding exclude structure. Otherwise, checks whether name
725+
* itself (which is presumably a file) is excluded.
724726
*
725727
* A path to a directory known to be excluded is left in check->path to
726728
* optimize for repeated checks for files in the same excluded directory.
727729
*/
728-
int is_path_excluded(struct path_exclude_check *check,
729-
const char *name, int namelen, int *dtype)
730+
struct exclude *last_exclude_matching_path(struct path_exclude_check *check,
731+
const char *name, int namelen,
732+
int *dtype)
730733
{
731734
int i;
732735
struct strbuf *path = &check->path;
736+
struct exclude *exclude;
733737

734738
/*
735739
* we allow the caller to pass namelen as an optimization; it
@@ -739,28 +743,53 @@ int is_path_excluded(struct path_exclude_check *check,
739743
if (namelen < 0)
740744
namelen = strlen(name);
741745

746+
/*
747+
* If path is non-empty, and name is equal to path or a
748+
* subdirectory of path, name should be excluded, because
749+
* it's inside a directory which is already known to be
750+
* excluded and was previously left in check->path.
751+
*/
742752
if (path->len &&
743753
path->len <= namelen &&
744754
!memcmp(name, path->buf, path->len) &&
745755
(!name[path->len] || name[path->len] == '/'))
746-
return 1;
756+
return check->exclude;
747757

748758
strbuf_setlen(path, 0);
749759
for (i = 0; name[i]; i++) {
750760
int ch = name[i];
751761

752762
if (ch == '/') {
753763
int dt = DT_DIR;
754-
if (is_excluded(check->dir, path->buf, &dt))
755-
return 1;
764+
exclude = last_exclude_matching(check->dir,
765+
path->buf, &dt);
766+
if (exclude) {
767+
check->exclude = exclude;
768+
return exclude;
769+
}
756770
}
757771
strbuf_addch(path, ch);
758772
}
759773

760774
/* An entry in the index; cannot be a directory with subentries */
761775
strbuf_setlen(path, 0);
762776

763-
return is_excluded(check->dir, name, dtype);
777+
return last_exclude_matching(check->dir, name, dtype);
778+
}
779+
780+
/*
781+
* Is this name excluded? This is for a caller like show_files() that
782+
* do not honor directory hierarchy and iterate through paths that are
783+
* possibly in an ignored directory.
784+
*/
785+
int is_path_excluded(struct path_exclude_check *check,
786+
const char *name, int namelen, int *dtype)
787+
{
788+
struct exclude *exclude =
789+
last_exclude_matching_path(check, name, namelen, dtype);
790+
if (exclude)
791+
return exclude->flags & EXC_FLAG_NEGATIVE ? 0 : 1;
792+
return 0;
764793
}
765794

766795
static struct dir_entry *dir_entry_new(const char *pathname, int len)

dir.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,13 @@ extern int match_pathname(const char *, int,
119119
*/
120120
struct path_exclude_check {
121121
struct dir_struct *dir;
122+
struct exclude *exclude;
122123
struct strbuf path;
123124
};
124125
extern void path_exclude_check_init(struct path_exclude_check *, struct dir_struct *);
125126
extern void path_exclude_check_clear(struct path_exclude_check *);
127+
extern struct exclude *last_exclude_matching_path(struct path_exclude_check *, const char *,
128+
int namelen, int *dtype);
126129
extern int is_path_excluded(struct path_exclude_check *, const char *, int namelen, int *dtype);
127130

128131

0 commit comments

Comments
 (0)