dir.c: don't exclude whole dir prematurely

If there is a pattern "!foo/bar", this patch makes it not exclude
"foo" right away. This gives us a chance to examine "foo" and
re-include "foo/bar".

Helped-by: brian m. carlson <sandals@crustytoothpaste.net>
Helped-by: Micha Wiedenmann <mw-u2@gmx.de>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Nguyễn Thái Ngọc Duy
2016-02-15 16:03:39 +07:00
committed by Junio C Hamano
parent c62a91736a
commit d589a67ece
4 changed files with 276 additions and 10 deletions

View File

@ -175,13 +175,10 @@ test_expect_success 'negated exclude matches can override previous ones' '
grep "^a.1" output
'
test_expect_success 'excluded directory overrides content patterns' '
test_expect_success 'excluded directory does not override content patterns' '
git ls-files --others --exclude="one" --exclude="!one/a.1" >output &&
if grep "^one/a.1" output
then
false
fi
grep "^one/a.1" output
'
test_expect_success 'negated directory doesn'\''t affect content patterns' '

View File

@ -0,0 +1,153 @@
#!/bin/sh
test_description='test re-include patterns'
. ./test-lib.sh
test_expect_success 'setup' '
mkdir -p fooo foo/bar tmp &&
touch abc foo/def foo/bar/ghi foo/bar/bar
'
test_expect_success 'no match, do not enter subdir and waste cycles' '
cat >.gitignore <<-\EOF &&
/tmp
/foo
!fooo/bar/bar
EOF
GIT_TRACE_EXCLUDE="$(pwd)/tmp/trace" git ls-files -o --exclude-standard >tmp/actual &&
! grep "enter .foo/.\$" tmp/trace &&
cat >tmp/expected <<-\EOF &&
.gitignore
abc
EOF
test_cmp tmp/expected tmp/actual
'
test_expect_success 'match, excluded by literal pathname pattern' '
cat >.gitignore <<-\EOF &&
/tmp
/fooo
/foo
!foo/bar/bar
EOF
cat >fooo/.gitignore <<-\EOF &&
!/*
EOF git ls-files -o --exclude-standard >tmp/actual &&
cat >tmp/expected <<-\EOF &&
.gitignore
abc
foo/bar/bar
EOF
test_cmp tmp/expected tmp/actual
'
test_expect_success 'match, excluded by wildcard pathname pattern' '
cat >.gitignore <<-\EOF &&
/tmp
/fooo
/fo?
!foo/bar/bar
EOF
git ls-files -o --exclude-standard >tmp/actual &&
cat >tmp/expected <<-\EOF &&
.gitignore
abc
foo/bar/bar
EOF
test_cmp tmp/expected tmp/actual
'
test_expect_success 'match, excluded by literal basename pattern' '
cat >.gitignore <<-\EOF &&
/tmp
/fooo
foo
!foo/bar/bar
EOF
git ls-files -o --exclude-standard >tmp/actual &&
cat >tmp/expected <<-\EOF &&
.gitignore
abc
foo/bar/bar
EOF
test_cmp tmp/expected tmp/actual
'
test_expect_success 'match, excluded by wildcard basename pattern' '
cat >.gitignore <<-\EOF &&
/tmp
/fooo
fo?
!foo/bar/bar
EOF
git ls-files -o --exclude-standard >tmp/actual &&
cat >tmp/expected <<-\EOF &&
.gitignore
abc
foo/bar/bar
EOF
test_cmp tmp/expected tmp/actual
'
test_expect_success 'match, excluded by literal mustbedir, basename pattern' '
cat >.gitignore <<-\EOF &&
/tmp
/fooo
foo/
!foo/bar/bar
EOF
git ls-files -o --exclude-standard >tmp/actual &&
cat >tmp/expected <<-\EOF &&
.gitignore
abc
foo/bar/bar
EOF
test_cmp tmp/expected tmp/actual
'
test_expect_success 'match, excluded by literal mustbedir, pathname pattern' '
cat >.gitignore <<-\EOF &&
/tmp
/fooo
/foo/
!foo/bar/bar
EOF
git ls-files -o --exclude-standard >tmp/actual &&
cat >tmp/expected <<-\EOF &&
.gitignore
abc
foo/bar/bar
EOF
test_cmp tmp/expected tmp/actual
'
test_expect_success 'prepare for nested negatives' '
cat >.git/info/exclude <<-\EOF &&
/.gitignore
/tmp
/foo
/abc
EOF
git ls-files -o --exclude-standard >tmp/actual &&
test_must_be_empty tmp/actual &&
mkdir -p 1/2/3/4 &&
touch 1/f 1/2/f 1/2/3/f 1/2/3/4/f
'
test_expect_success 'match, literal pathname, nested negatives' '
cat >.gitignore <<-\EOF &&
/1
!1/2
1/2/3
!1/2/3/4
EOF
git ls-files -o --exclude-standard >tmp/actual &&
cat >tmp/expected <<-\EOF &&
1/2/3/4/f
1/2/f
EOF
test_cmp tmp/expected tmp/actual
'
test_done