mirror of
https://github.com/git/git.git
synced 2024-11-24 18:33:43 +08:00
Support "**" wildcard in .gitignore and .gitattributes
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:
parent
4c251e5cb5
commit
237ec6e40d
@ -96,6 +96,25 @@ PATTERN FORMAT
|
||||
For example, "/{asterisk}.c" matches "cat-file.c" but not
|
||||
"mozilla-sha1/sha1.c".
|
||||
|
||||
Two consecutive asterisks ("`**`") in patterns matched against
|
||||
full pathname may have special meaning:
|
||||
|
||||
- A leading "`**`" followed by a slash means match in all
|
||||
directories. For example, "`**/foo`" matches file or directory
|
||||
"`foo`" anywhere, the same as pattern "`foo`". "**/foo/bar"
|
||||
matches file or directory "`bar`" anywhere that is directly
|
||||
under directory "`foo`".
|
||||
|
||||
- A trailing "/**" matches everything inside. For example,
|
||||
"abc/**" matches all files inside directory "abc", relative
|
||||
to the location of the `.gitignore` file, with infinite depth.
|
||||
|
||||
- A slash followed by two consecutive asterisks then a slash
|
||||
matches zero or more directories. For example, "`a/**/b`"
|
||||
matches "`a/b`", "`a/x/b`", "`a/x/y/b`" and so on.
|
||||
|
||||
- Other consecutive asterisks are considered invalid.
|
||||
|
||||
NOTES
|
||||
-----
|
||||
|
||||
|
4
dir.c
4
dir.c
@ -8,6 +8,7 @@
|
||||
#include "cache.h"
|
||||
#include "dir.h"
|
||||
#include "refs.h"
|
||||
#include "wildmatch.h"
|
||||
|
||||
struct path_simplify {
|
||||
int len;
|
||||
@ -593,7 +594,8 @@ int match_pathname(const char *pathname, int pathlen,
|
||||
namelen -= prefix;
|
||||
}
|
||||
|
||||
return fnmatch_icase(pattern, name, FNM_PATHNAME) == 0;
|
||||
return wildmatch(pattern, name,
|
||||
ignore_case ? FNM_CASEFOLD : 0) == 0;
|
||||
}
|
||||
|
||||
/* Scan the list and let the last match determine the fate.
|
||||
|
@ -216,6 +216,43 @@ test_expect_success 'patterns starting with exclamation' '
|
||||
attr_check "!f" foo
|
||||
'
|
||||
|
||||
test_expect_success '"**" test' '
|
||||
echo "**/f foo=bar" >.gitattributes &&
|
||||
cat <<\EOF >expect &&
|
||||
f: foo: bar
|
||||
a/f: foo: bar
|
||||
a/b/f: foo: bar
|
||||
a/b/c/f: foo: bar
|
||||
EOF
|
||||
git check-attr foo -- "f" >actual 2>err &&
|
||||
git check-attr foo -- "a/f" >>actual 2>>err &&
|
||||
git check-attr foo -- "a/b/f" >>actual 2>>err &&
|
||||
git check-attr foo -- "a/b/c/f" >>actual 2>>err &&
|
||||
test_cmp expect actual &&
|
||||
test_line_count = 0 err
|
||||
'
|
||||
|
||||
test_expect_success '"**" with no slashes test' '
|
||||
echo "a**f foo=bar" >.gitattributes &&
|
||||
git check-attr foo -- "f" >actual &&
|
||||
cat <<\EOF >expect &&
|
||||
f: foo: unspecified
|
||||
af: foo: bar
|
||||
axf: foo: bar
|
||||
a/f: foo: unspecified
|
||||
a/b/f: foo: unspecified
|
||||
a/b/c/f: foo: unspecified
|
||||
EOF
|
||||
git check-attr foo -- "f" >actual 2>err &&
|
||||
git check-attr foo -- "af" >>actual 2>err &&
|
||||
git check-attr foo -- "axf" >>actual 2>err &&
|
||||
git check-attr foo -- "a/f" >>actual 2>>err &&
|
||||
git check-attr foo -- "a/b/f" >>actual 2>>err &&
|
||||
git check-attr foo -- "a/b/c/f" >>actual 2>>err &&
|
||||
test_cmp expect actual &&
|
||||
test_line_count = 0 err
|
||||
'
|
||||
|
||||
test_expect_success 'setup bare' '
|
||||
git clone --bare . bare.git &&
|
||||
cd bare.git
|
||||
|
@ -220,4 +220,22 @@ test_expect_success 'pattern matches prefix completely' '
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'ls-files with "**" patterns' '
|
||||
cat <<\EOF >expect &&
|
||||
a.1
|
||||
one/a.1
|
||||
one/two/a.1
|
||||
three/a.1
|
||||
EOF
|
||||
git ls-files -o -i --exclude "**/a.1" >actual
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
|
||||
test_expect_success 'ls-files with "**" patterns and no slashes' '
|
||||
: >expect &&
|
||||
git ls-files -o -i --exclude "one**a.1" >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_done
|
||||
|
Loading…
Reference in New Issue
Block a user