dir.c: keep track of where patterns came from
For exclude patterns read in from files, the filename is stored in the exclude list, and the originating line number is stored in the individual exclude (counting starting at 1). For exclude patterns provided on the command line, a string describing the source of the patterns is stored in the exclude list, and the sequence number assigned to each exclude pattern is negative, with counting starting at -1. So for example the 2nd pattern provided via --exclude would be numbered -2. This allows any future consumers of that data to easily distinguish between exclude patterns from files vs. from the CLI. Signed-off-by: Adam Spiers <git@adamspiers.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
c082df2453
commit
c04318e46a
@ -97,10 +97,10 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
|
|||||||
if (!ignored)
|
if (!ignored)
|
||||||
setup_standard_excludes(&dir);
|
setup_standard_excludes(&dir);
|
||||||
|
|
||||||
add_exclude_list(&dir, EXC_CMDL);
|
add_exclude_list(&dir, EXC_CMDL, "--exclude option");
|
||||||
for (i = 0; i < exclude_list.nr; i++)
|
for (i = 0; i < exclude_list.nr; i++)
|
||||||
add_exclude(exclude_list.items[i].string, "", 0,
|
add_exclude(exclude_list.items[i].string, "", 0,
|
||||||
&dir.exclude_list_group[EXC_CMDL].el[0]);
|
&dir.exclude_list_group[EXC_CMDL].el[0], -(i+1));
|
||||||
|
|
||||||
pathspec = get_pathspec(prefix, argv);
|
pathspec = get_pathspec(prefix, argv);
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ static int error_unmatch;
|
|||||||
static char *ps_matched;
|
static char *ps_matched;
|
||||||
static const char *with_tree;
|
static const char *with_tree;
|
||||||
static int exc_given;
|
static int exc_given;
|
||||||
|
static int exclude_args;
|
||||||
|
|
||||||
static const char *tag_cached = "";
|
static const char *tag_cached = "";
|
||||||
static const char *tag_unmerged = "";
|
static const char *tag_unmerged = "";
|
||||||
@ -423,7 +424,7 @@ static int option_parse_exclude(const struct option *opt,
|
|||||||
struct exclude_list_group *group = opt->value;
|
struct exclude_list_group *group = opt->value;
|
||||||
|
|
||||||
exc_given = 1;
|
exc_given = 1;
|
||||||
add_exclude(arg, "", 0, &group->el[0]);
|
add_exclude(arg, "", 0, &group->el[0], --exclude_args);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -524,7 +525,7 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
|
|||||||
if (read_cache() < 0)
|
if (read_cache() < 0)
|
||||||
die("index file corrupt");
|
die("index file corrupt");
|
||||||
|
|
||||||
add_exclude_list(&dir, EXC_CMDL);
|
add_exclude_list(&dir, EXC_CMDL, "--exclude option");
|
||||||
argc = parse_options(argc, argv, prefix, builtin_ls_files_options,
|
argc = parse_options(argc, argv, prefix, builtin_ls_files_options,
|
||||||
ls_files_usage, 0);
|
ls_files_usage, 0);
|
||||||
if (show_tag || show_valid_bit) {
|
if (show_tag || show_valid_bit) {
|
||||||
|
26
dir.c
26
dir.c
@ -349,7 +349,7 @@ void parse_exclude_pattern(const char **pattern,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void add_exclude(const char *string, const char *base,
|
void add_exclude(const char *string, const char *base,
|
||||||
int baselen, struct exclude_list *el)
|
int baselen, struct exclude_list *el, int srcpos)
|
||||||
{
|
{
|
||||||
struct exclude *x;
|
struct exclude *x;
|
||||||
int patternlen;
|
int patternlen;
|
||||||
@ -373,8 +373,10 @@ void add_exclude(const char *string, const char *base,
|
|||||||
x->base = base;
|
x->base = base;
|
||||||
x->baselen = baselen;
|
x->baselen = baselen;
|
||||||
x->flags = flags;
|
x->flags = flags;
|
||||||
|
x->srcpos = srcpos;
|
||||||
ALLOC_GROW(el->excludes, el->nr + 1, el->alloc);
|
ALLOC_GROW(el->excludes, el->nr + 1, el->alloc);
|
||||||
el->excludes[el->nr++] = x;
|
el->excludes[el->nr++] = x;
|
||||||
|
x->el = el;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *read_skip_worktree_file_from_index(const char *path, size_t *size)
|
static void *read_skip_worktree_file_from_index(const char *path, size_t *size)
|
||||||
@ -425,7 +427,7 @@ int add_excludes_from_file_to_list(const char *fname,
|
|||||||
int check_index)
|
int check_index)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
int fd, i;
|
int fd, i, lineno = 1;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
char *buf, *entry;
|
char *buf, *entry;
|
||||||
|
|
||||||
@ -467,15 +469,17 @@ int add_excludes_from_file_to_list(const char *fname,
|
|||||||
if (buf[i] == '\n') {
|
if (buf[i] == '\n') {
|
||||||
if (entry != buf + i && entry[0] != '#') {
|
if (entry != buf + i && entry[0] != '#') {
|
||||||
buf[i - (i && buf[i-1] == '\r')] = 0;
|
buf[i - (i && buf[i-1] == '\r')] = 0;
|
||||||
add_exclude(entry, base, baselen, el);
|
add_exclude(entry, base, baselen, el, lineno);
|
||||||
}
|
}
|
||||||
|
lineno++;
|
||||||
entry = buf + i + 1;
|
entry = buf + i + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct exclude_list *add_exclude_list(struct dir_struct *dir, int group_type)
|
struct exclude_list *add_exclude_list(struct dir_struct *dir,
|
||||||
|
int group_type, const char *src)
|
||||||
{
|
{
|
||||||
struct exclude_list *el;
|
struct exclude_list *el;
|
||||||
struct exclude_list_group *group;
|
struct exclude_list_group *group;
|
||||||
@ -484,6 +488,7 @@ struct exclude_list *add_exclude_list(struct dir_struct *dir, int group_type)
|
|||||||
ALLOC_GROW(group->el, group->nr + 1, group->alloc);
|
ALLOC_GROW(group->el, group->nr + 1, group->alloc);
|
||||||
el = &group->el[group->nr++];
|
el = &group->el[group->nr++];
|
||||||
memset(el, 0, sizeof(*el));
|
memset(el, 0, sizeof(*el));
|
||||||
|
el->src = src;
|
||||||
return el;
|
return el;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -493,7 +498,7 @@ struct exclude_list *add_exclude_list(struct dir_struct *dir, int group_type)
|
|||||||
void add_excludes_from_file(struct dir_struct *dir, const char *fname)
|
void add_excludes_from_file(struct dir_struct *dir, const char *fname)
|
||||||
{
|
{
|
||||||
struct exclude_list *el;
|
struct exclude_list *el;
|
||||||
el = add_exclude_list(dir, EXC_FILE);
|
el = add_exclude_list(dir, EXC_FILE, fname);
|
||||||
if (add_excludes_from_file_to_list(fname, "", 0, el, 0) < 0)
|
if (add_excludes_from_file_to_list(fname, "", 0, el, 0) < 0)
|
||||||
die("cannot use %s as an exclude file", fname);
|
die("cannot use %s as an exclude file", fname);
|
||||||
}
|
}
|
||||||
@ -524,6 +529,7 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)
|
|||||||
break;
|
break;
|
||||||
el = &group->el[dir->exclude_stack->exclude_ix];
|
el = &group->el[dir->exclude_stack->exclude_ix];
|
||||||
dir->exclude_stack = stk->prev;
|
dir->exclude_stack = stk->prev;
|
||||||
|
free((char *)el->src); /* see strdup() below */
|
||||||
clear_exclude_list(el);
|
clear_exclude_list(el);
|
||||||
free(stk);
|
free(stk);
|
||||||
group->nr--;
|
group->nr--;
|
||||||
@ -550,7 +556,15 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)
|
|||||||
memcpy(dir->basebuf + current, base + current,
|
memcpy(dir->basebuf + current, base + current,
|
||||||
stk->baselen - current);
|
stk->baselen - current);
|
||||||
strcpy(dir->basebuf + stk->baselen, dir->exclude_per_dir);
|
strcpy(dir->basebuf + stk->baselen, dir->exclude_per_dir);
|
||||||
el = add_exclude_list(dir, EXC_DIRS);
|
/*
|
||||||
|
* dir->basebuf gets reused by the traversal, but we
|
||||||
|
* need fname to remain unchanged to ensure the src
|
||||||
|
* member of each struct exclude correctly
|
||||||
|
* back-references its source file. Other invocations
|
||||||
|
* of add_exclude_list provide stable strings, so we
|
||||||
|
* strdup() and free() here in the caller.
|
||||||
|
*/
|
||||||
|
el = add_exclude_list(dir, EXC_DIRS, strdup(dir->basebuf));
|
||||||
stk->exclude_ix = group->nr - 1;
|
stk->exclude_ix = group->nr - 1;
|
||||||
add_excludes_from_file_to_list(dir->basebuf,
|
add_excludes_from_file_to_list(dir->basebuf,
|
||||||
dir->basebuf, stk->baselen,
|
dir->basebuf, stk->baselen,
|
||||||
|
21
dir.h
21
dir.h
@ -25,16 +25,32 @@ struct dir_entry {
|
|||||||
struct exclude_list {
|
struct exclude_list {
|
||||||
int nr;
|
int nr;
|
||||||
int alloc;
|
int alloc;
|
||||||
|
|
||||||
/* remember pointer to exclude file contents so we can free() */
|
/* remember pointer to exclude file contents so we can free() */
|
||||||
char *filebuf;
|
char *filebuf;
|
||||||
|
|
||||||
|
/* origin of list, e.g. path to filename, or descriptive string */
|
||||||
|
const char *src;
|
||||||
|
|
||||||
struct exclude {
|
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;
|
const char *pattern;
|
||||||
int patternlen;
|
int patternlen;
|
||||||
int nowildcardlen;
|
int nowildcardlen;
|
||||||
const char *base;
|
const char *base;
|
||||||
int baselen;
|
int baselen;
|
||||||
int flags;
|
int flags;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Counting starts from 1 for line numbers in ignore files,
|
||||||
|
* and from -1 decrementing for patterns from CLI args.
|
||||||
|
*/
|
||||||
|
int srcpos;
|
||||||
} **excludes;
|
} **excludes;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -144,13 +160,14 @@ 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 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);
|
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,
|
extern int add_excludes_from_file_to_list(const char *fname, const char *base, int baselen,
|
||||||
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 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 parse_exclude_pattern(const char **string, int *patternlen, int *flags, int *nowildcardlen);
|
||||||
extern void add_exclude(const char *string, const char *base,
|
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_exclude_list(struct exclude_list *el);
|
||||||
extern int file_exists(const char *);
|
extern int file_exists(const char *);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user