git/t/t3001-ls-files-others-exclude.sh
Junio C Hamano d6b8fc303b gitignore(5): Allow "foo/" in ignore list to match directory "foo"
A pattern "foo/" in the exclude list did not match directory
"foo", but a pattern "foo" did.  This attempts to extend the
exclude mechanism so that it would while not matching a regular
file or a symbolic link "foo".  In order to differentiate a
directory and non directory, this passes down the type of path
being checked to excluded() function.

A downside is that the recursive directory walk may need to run
lstat(2) more often on systems whose "struct dirent" do not give
the type of the entry; earlier it did not have to do so for an
excluded path, but we now need to figure out if a path is a
directory before deciding to exclude it.  This is especially bad
because an idea similar to the earlier CE_UPTODATE optimization
to reduce number of lstat(2) calls would by definition not apply
to the codepaths involved, as (1) directories will not be
registered in the index, and (2) excluded paths will not be in
the index anyway.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-02-05 00:46:49 -08:00

144 lines
2.2 KiB
Bash
Executable File

#!/bin/sh
#
# Copyright (c) 2005 Junio C Hamano
#
test_description='git ls-files --others --exclude
This test runs git ls-files --others and tests --exclude patterns.
'
. ./test-lib.sh
rm -fr one three
for dir in . one one/two three
do
mkdir -p $dir &&
for i in 1 2 3 4 5 6 7 8
do
>$dir/a.$i
done
done
cat >expect <<EOF
a.2
a.4
a.5
a.8
one/a.3
one/a.4
one/a.5
one/a.7
one/two/a.2
one/two/a.3
one/two/a.5
one/two/a.7
one/two/a.8
three/a.2
three/a.3
three/a.4
three/a.5
three/a.8
EOF
echo '.gitignore
output
expect
.gitignore
*.7
!*.8' >.git/ignore
echo '*.1
/*.3
!*.6' >.gitignore
echo '*.2
two/*.4
!*.7
*.8' >one/.gitignore
echo '!*.2
!*.8' >one/two/.gitignore
test_expect_success \
'git ls-files --others with various exclude options.' \
'git ls-files --others \
--exclude=\*.6 \
--exclude-per-directory=.gitignore \
--exclude-from=.git/ignore \
>output &&
git diff expect output'
# Test \r\n (MSDOS-like systems)
printf '*.1\r\n/*.3\r\n!*.6\r\n' >.gitignore
test_expect_success \
'git ls-files --others with \r\n line endings.' \
'git ls-files --others \
--exclude=\*.6 \
--exclude-per-directory=.gitignore \
--exclude-from=.git/ignore \
>output &&
git diff expect output'
cat > excludes-file << EOF
*.[1-8]
e*
EOF
git config core.excludesFile excludes-file
git status | grep "^# " > output
cat > expect << EOF
# .gitignore
# a.6
# one/
# output
# three/
EOF
test_expect_success 'git-status honours core.excludesfile' \
'diff -u expect output'
test_expect_success 'trailing slash in exclude allows directory match(1)' '
git ls-files --others --exclude=one/ >output &&
if grep "^one/" output
then
echo Ooops
false
else
: happy
fi
'
test_expect_success 'trailing slash in exclude allows directory match (2)' '
git ls-files --others --exclude=one/two/ >output &&
if grep "^one/two/" output
then
echo Ooops
false
else
: happy
fi
'
test_expect_success 'trailing slash in exclude forces directory match (1)' '
>two
git ls-files --others --exclude=two/ >output &&
grep "^two" output
'
test_expect_success 'trailing slash in exclude forces directory match (2)' '
git ls-files --others --exclude=one/a.1/ >output &&
grep "^one/a.1" output
'
test_done