diff options
author | Adam Spiers <git@adamspiers.org> | 2013-01-06 16:58:04 +0000 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2013-01-06 14:26:37 -0800 |
commit | c04318e46aae79b8b8df059e2118519d83dfee12 (patch) | |
tree | 714436b653a34517e552024b0d1d2c9f94644997 /dir.c | |
parent | c082df24539329c2e75395cf378f0a3fe187c028 (diff) | |
download | git-c04318e46aae79b8b8df059e2118519d83dfee12.tar.gz git-c04318e46aae79b8b8df059e2118519d83dfee12.tar.xz |
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>
Diffstat (limited to 'dir.c')
-rw-r--r-- | dir.c | 26 |
1 files changed, 20 insertions, 6 deletions
@@ -349,7 +349,7 @@ void parse_exclude_pattern(const char **pattern, } 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; int patternlen; @@ -373,8 +373,10 @@ void add_exclude(const char *string, const char *base, x->base = base; x->baselen = baselen; x->flags = flags; + x->srcpos = srcpos; ALLOC_GROW(el->excludes, el->nr + 1, el->alloc); el->excludes[el->nr++] = x; + x->el = el; } 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) { struct stat st; - int fd, i; + int fd, i, lineno = 1; size_t size = 0; char *buf, *entry; @@ -467,15 +469,17 @@ int add_excludes_from_file_to_list(const char *fname, if (buf[i] == '\n') { if (entry != buf + i && entry[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; } } 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_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); el = &group->el[group->nr++]; memset(el, 0, sizeof(*el)); + el->src = src; 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) { 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) 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; el = &group->el[dir->exclude_stack->exclude_ix]; dir->exclude_stack = stk->prev; + free((char *)el->src); /* see strdup() below */ clear_exclude_list(el); free(stk); 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, stk->baselen - current); 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; add_excludes_from_file_to_list(dir->basebuf, dir->basebuf, stk->baselen, |