Skip to content

Commit

Permalink
Fix per-directory exclude handing for "git add"
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Junio C Hamano committed Nov 17, 2007
1 parent dcf0c16 commit 0e06cc8
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 2 deletions.
6 changes: 4 additions & 2 deletions dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -626,14 +626,16 @@ static void free_simplify(struct path_simplify *simplify)
int read_directory(struct dir_struct *dir, const char *path, const char *base, int baselen, const char **pathspec)
{
struct path_simplify *simplify = create_simplify(pathspec);
char *pp = NULL;

/*
* Make sure to do the per-directory exclude for all the
* directories leading up to our base.
*/
if (baselen) {
if (dir->exclude_per_dir) {
char *p, *pp = xmalloc(baselen+1);
char *p;
pp = xmalloc(baselen+1);
memcpy(pp, base, baselen+1);
p = pp;
while (1) {
Expand All @@ -649,12 +651,12 @@ int read_directory(struct dir_struct *dir, const char *path, const char *base, i
else
p = pp + baselen;
}
free(pp);
}
}

read_directory_recursive(dir, path, base, baselen, 0, simplify);
free_simplify(simplify);
free(pp);
qsort(dir->entries, dir->nr, sizeof(struct dir_entry *), cmp_name);
qsort(dir->ignored, dir->ignored_nr, sizeof(struct dir_entry *), cmp_name);
return dir->nr;
Expand Down
24 changes: 24 additions & 0 deletions t/t3700-add.sh
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,33 @@ test_expect_success 'add ignored ones with -f' '
git ls-files --error-unmatch d.ig/d.if d.ig/d.ig
'

test_expect_success 'add ignored ones with -f' '
rm -f .git/index &&
git add -f d.?? &&
git ls-files --error-unmatch d.ig/d.if d.ig/d.ig
'

test_expect_success '.gitignore with subdirectory' '
rm -f .git/index &&
mkdir -p sub/dir &&
echo "!dir/a.*" >sub/.gitignore &&
>sub/a.ig &&
>sub/dir/a.ig &&
git add sub/dir &&
git ls-files --error-unmatch sub/dir/a.ig &&
rm -f .git/index &&
(
cd sub/dir &&
git add .
) &&
git ls-files --error-unmatch sub/dir/a.ig
'

mkdir 1 1/2 1/3
touch 1/2/a 1/3/b 1/2/c
test_expect_success 'check correct prefix detection' '
rm -f .git/index &&
git add 1/2/a 1/3/b 1/2/c
'

Expand Down

0 comments on commit 0e06cc8

Please sign in to comment.