Merge branch 'maint'
[git.git] / dir.h
diff --git a/dir.h b/dir.h
index ae1bc467ae909e6db151b055e212ded45fac34f6..c3eb4b520effb63e73653194e4266c0ef628cccd 100644 (file)
--- a/dir.h
+++ b/dir.h
@@ -16,21 +16,41 @@ struct dir_entry {
 #define EXC_FLAG_NEGATIVE 16
 
 /*
- * Each .gitignore file will be parsed into patterns which are then
- * appended to the relevant exclude_list (either EXC_DIRS or
- * EXC_FILE).  exclude_lists are also used to represent the list of
- * --exclude values passed via CLI args (EXC_CMDL).
+ * Each excludes file will be parsed into a fresh exclude_list which
+ * is appended to the relevant exclude_list_group (either EXC_DIRS or
+ * EXC_FILE).  An exclude_list within the EXC_CMDL exclude_list_group
+ * can also be used to represent the list of --exclude values passed
+ * via CLI args.
  */
 struct exclude_list {
        int nr;
        int alloc;
+
+       /* remember pointer to exclude file contents so we can free() */
+       char *filebuf;
+
+       /* origin of list, e.g. path to filename, or descriptive string */
+       const char *src;
+
        struct exclude {
+               /*
+                * This allows callers of last_exclude_matching() etc.
+                * to determine the origin of the matching pattern.
+                */
+               struct exclude_list *el;
+
                const char *pattern;
                int patternlen;
                int nowildcardlen;
                const char *base;
                int baselen;
                int flags;
+
+               /*
+                * Counting starts from 1 for line numbers in ignore files,
+                * and from -1 decrementing for patterns from CLI args.
+                */
+               int srcpos;
        } **excludes;
 };
 
@@ -42,9 +62,13 @@ struct exclude_list {
  */
 struct exclude_stack {
        struct exclude_stack *prev; /* the struct exclude_stack for the parent directory */
-       char *filebuf; /* remember pointer to per-directory exclude file contents so we can free() */
        int baselen;
-       int exclude_ix;
+       int exclude_ix; /* index of exclude_list within EXC_DIRS exclude_list_group */
+};
+
+struct exclude_list_group {
+       int nr, alloc;
+       struct exclude_list *el;
 };
 
 struct dir_struct {
@@ -62,16 +86,23 @@ struct dir_struct {
 
        /* Exclude info */
        const char *exclude_per_dir;
-       struct exclude_list exclude_list[3];
+
        /*
-        * We maintain three exclude pattern lists:
+        * We maintain three groups of exclude pattern lists:
+        *
         * EXC_CMDL lists patterns explicitly given on the command line.
         * EXC_DIRS lists patterns obtained from per-directory ignore files.
-        * EXC_FILE lists patterns from fallback ignore files.
+        * EXC_FILE lists patterns from fallback ignore files, e.g.
+        *   - .git/info/exclude
+        *   - core.excludesfile
+        *
+        * Each group contains multiple exclude lists, a single list
+        * per source.
         */
 #define EXC_CMDL 0
 #define EXC_DIRS 1
 #define EXC_FILE 2
+       struct exclude_list_group exclude_list_group[3];
 
        /*
         * Temporary variables which are used during loading of the
@@ -85,6 +116,12 @@ struct dir_struct {
        char basebuf[PATH_MAX];
 };
 
+/*
+ * The ordering of these constants is significant, with
+ * higher-numbered match types signifying "closer" (i.e. more
+ * specific) matches which will override lower-numbered match types
+ * when populating the seen[] array.
+ */
 #define MATCHED_RECURSIVELY 1
 #define MATCHED_FNMATCH 2
 #define MATCHED_EXACTLY 3
@@ -129,13 +166,16 @@ extern struct exclude *last_exclude_matching_path(struct path_exclude_check *, c
 extern int is_path_excluded(struct path_exclude_check *, const char *, int namelen, int *dtype);
 
 
+extern struct exclude_list *add_exclude_list(struct dir_struct *dir,
+                                            int group_type, const char *src);
 extern int add_excludes_from_file_to_list(const char *fname, const char *base, int baselen,
-                                         char **buf_p, struct exclude_list *el, int check_index);
+                                         struct exclude_list *el, int check_index);
 extern void add_excludes_from_file(struct dir_struct *, const char *fname);
 extern void parse_exclude_pattern(const char **string, int *patternlen, int *flags, int *nowildcardlen);
 extern void add_exclude(const char *string, const char *base,
-                       int baselen, struct exclude_list *el);
+                       int baselen, struct exclude_list *el, int srcpos);
 extern void clear_exclude_list(struct exclude_list *el);
+extern void clear_directory(struct dir_struct *dir);
 extern int file_exists(const char *);
 
 extern int is_inside_dir(const char *dir);