Skip to content

Commit 41a7aa5

Browse files
committed
Fix per-directory exclude handing for "git add"
In "dir_struct", each exclusion element in the exclusion stack records a base string (pointer to the beginning with length) so that we can tell where it came from, but this pointer is just pointing at the parameter that is given by the caller to the push_exclude_per_directory() function. While read_directory_recursive() runs, calls to excluded() makes use the data in the exclusion elements, including this base string. The caller of read_directory_recursive() is not supposed to free the buffer it gave to push_exclude_per_directory() earlier, until it returns. The test case Bruce Stephens gave in the mailing list discussion was simplified and added to the t3700 test. Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent c1a95fa commit 41a7aa5

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

dir.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -654,14 +654,16 @@ static void free_simplify(struct path_simplify *simplify)
654654
int read_directory(struct dir_struct *dir, const char *path, const char *base, int baselen, const char **pathspec)
655655
{
656656
struct path_simplify *simplify = create_simplify(pathspec);
657+
char *pp = NULL;
657658

658659
/*
659660
* Make sure to do the per-directory exclude for all the
660661
* directories leading up to our base.
661662
*/
662663
if (baselen) {
663664
if (dir->exclude_per_dir) {
664-
char *p, *pp = xmalloc(baselen+1);
665+
char *p;
666+
pp = xmalloc(baselen+1);
665667
memcpy(pp, base, baselen+1);
666668
p = pp;
667669
while (1) {
@@ -677,12 +679,12 @@ int read_directory(struct dir_struct *dir, const char *path, const char *base, i
677679
else
678680
p = pp + baselen;
679681
}
680-
free(pp);
681682
}
682683
}
683684

684685
read_directory_recursive(dir, path, base, baselen, 0, simplify);
685686
free_simplify(simplify);
687+
free(pp);
686688
qsort(dir->entries, dir->nr, sizeof(struct dir_entry *), cmp_name);
687689
qsort(dir->ignored, dir->ignored_nr, sizeof(struct dir_entry *), cmp_name);
688690
return dir->nr;

t/t3700-add.sh

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,33 @@ test_expect_success 'add ignored ones with -f' '
104104
git ls-files --error-unmatch d.ig/d.if d.ig/d.ig
105105
'
106106

107+
test_expect_success 'add ignored ones with -f' '
108+
rm -f .git/index &&
109+
git add -f d.?? &&
110+
git ls-files --error-unmatch d.ig/d.if d.ig/d.ig
111+
'
112+
113+
test_expect_success '.gitignore with subdirectory' '
114+
115+
rm -f .git/index &&
116+
mkdir -p sub/dir &&
117+
echo "!dir/a.*" >sub/.gitignore &&
118+
>sub/a.ig &&
119+
>sub/dir/a.ig &&
120+
git add sub/dir &&
121+
git ls-files --error-unmatch sub/dir/a.ig &&
122+
rm -f .git/index &&
123+
(
124+
cd sub/dir &&
125+
git add .
126+
) &&
127+
git ls-files --error-unmatch sub/dir/a.ig
128+
'
129+
107130
mkdir 1 1/2 1/3
108131
touch 1/2/a 1/3/b 1/2/c
109132
test_expect_success 'check correct prefix detection' '
133+
rm -f .git/index &&
110134
git add 1/2/a 1/3/b 1/2/c
111135
'
112136

0 commit comments

Comments
 (0)