Merge pull request #3745 from libgit2/cmn/ignore-starstar

Improve star-star matching
This commit is contained in:
Edward Thomson 2016-04-19 15:24:14 -04:00
commit 95fbc81daf
2 changed files with 44 additions and 5 deletions

View File

@ -93,11 +93,24 @@ p_fnmatchx(const char *pattern, const char *string, int flags, size_t recurs)
* It will be restored if/when we recurse below. * It will be restored if/when we recurse below.
*/ */
if (c == '*') { if (c == '*') {
flags &= ~FNM_PATHNAME;
while (c == '*')
c = *++pattern; c = *++pattern;
if (c == '/') /* star-star-slash is at the end, match by default */
if (c == EOS)
return 0;
/* Double-star must be at end or between slashes */
if (c != '/')
return (FNM_NOMATCH);
c = *++pattern; c = *++pattern;
do {
int e = p_fnmatchx(pattern, string, recurs_flags, recurs);
if (e != FNM_NOMATCH)
return e;
string = strchr(string, '/');
} while (string++);
/* If we get here, we didn't find a match */
return FNM_NOMATCH;
} }
if (*string == '.' && (flags & FNM_PERIOD) && if (*string == '.' && (flags & FNM_PERIOD) &&

View File

@ -132,6 +132,32 @@ void test_attr_ignore__leading_stars(void)
assert_is_ignored(false, "dir1/kid2/file"); assert_is_ignored(false, "dir1/kid2/file");
} }
void test_attr_ignore__globs_and_path_delimiters(void)
{
cl_git_rewritefile("attr/.gitignore", "foo/bar/**");
assert_is_ignored(true, "foo/bar/baz");
assert_is_ignored(true, "foo/bar/baz/quux");
cl_git_rewritefile("attr/.gitignore", "_*/");
assert_is_ignored(true, "sub/_test/a/file");
assert_is_ignored(false, "test_folder/file");
assert_is_ignored(true, "_test/file");
assert_is_ignored(true, "_test/a/file");
cl_git_rewritefile("attr/.gitignore", "**/_*/");
assert_is_ignored(true, "sub/_test/a/file");
assert_is_ignored(false, "test_folder/file");
assert_is_ignored(true, "_test/file");
assert_is_ignored(true, "_test/a/file");
cl_git_rewritefile("attr/.gitignore", "**/_*/foo/bar/*ux");
assert_is_ignored(true, "sub/_test/foo/bar/qux/file");
assert_is_ignored(true, "_test/foo/bar/qux/file");
assert_is_ignored(true, "_test/foo/bar/crux/file");
assert_is_ignored(false, "_test/foo/bar/code/file");
}
void test_attr_ignore__skip_gitignore_directory(void) void test_attr_ignore__skip_gitignore_directory(void)
{ {
cl_git_rewritefile("attr/.git/info/exclude", "/NewFolder\n/NewFolder/NewFolder"); cl_git_rewritefile("attr/.git/info/exclude", "/NewFolder\n/NewFolder/NewFolder");