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>
Adam Spiers committed
Dec 27, 2012 at 02:32 UTC
a35341a86ecf354d46cf326ed9e0ffbceb54309d
2 files changed
+41
-9
dir.c
+38
-9
@@ -709,6 +709,7 @@ void path_exclude_check_init(struct path_exclude_check *check,
709
struct dir_struct *dir)
710
{
711
check->dir = dir;
712
+ check->exclude = NULL;
713
strbuf_init(&check->path, 256);
714
}
715
@@ -718,18 +719,21 @@ void path_exclude_check_clear(struct path_exclude_check *check)
719
}
720
721
/*
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.
726
*
727
* A path to a directory known to be excluded is left in check->path to
728
* optimize for repeated checks for files in the same excluded directory.
729
*/
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)
733
{
734
int i;
735
struct strbuf *path = &check->path;
736
+ struct exclude *exclude;
737
738
/*
739
* we allow the caller to pass namelen as an optimization; it
@@ -739,11 +743,17 @@ int is_path_excluded(struct path_exclude_check *check,
743
if (namelen < 0)
744
namelen = strlen(name);
745
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
+ */
752
if (path->len &&
753
path->len <= namelen &&
754
!memcmp(name, path->buf, path->len) &&
755
(!name[path->len] || name[path->len] == '/'))
746
- return 1;
756
+ return check->exclude;
757
758
strbuf_setlen(path, 0);
759
for (i = 0; name[i]; i++) {
@@ -751,8 +761,12 @@ int is_path_excluded(struct path_exclude_check *check,
761
762
if (ch == '/') {
763
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
+ }
770
}
771
strbuf_addch(path, ch);
772
}
@@ -760,7 +774,22 @@ int is_path_excluded(struct path_exclude_check *check,
774
/* An entry in the index; cannot be a directory with subentries */
775
strbuf_setlen(path, 0);
776
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;
793
}
794
795
static struct dir_entry *dir_entry_new(const char *pathname, int len)
dir.h
+3
@@ -119,10 +119,13 @@ extern int match_pathname(const char *, int,
119
*/
120
struct path_exclude_check {
121
struct dir_struct *dir;
122
+ struct exclude *exclude;
123
struct strbuf path;
124
};
125
extern void path_exclude_check_init(struct path_exclude_check *, struct dir_struct *);
126
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);
129
extern int is_path_excluded(struct path_exclude_check *, const char *, int namelen, int *dtype);
130
131