diff --git a/src/fnmatch.c b/src/fnmatch.c index e3e47f37b..8e5424b75 100644 --- a/src/fnmatch.c +++ b/src/fnmatch.c @@ -30,6 +30,7 @@ p_fnmatchx(const char *pattern, const char *string, int flags, size_t recurs) const char *stringstart; char *newp; char c, test; + int recurs_flags = flags & ~FNM_PERIOD; if (recurs-- == 0) return FNM_NORES; @@ -53,9 +54,13 @@ p_fnmatchx(const char *pattern, const char *string, int flags, size_t recurs) break; case '*': c = *pattern; - /* Collapse multiple stars. */ - while (c == '*') + + /* Apply '**' to overwrite PATHNAME match */ + if (c == '*') { + flags &= ~FNM_PATHNAME; + while (c == '*') c = *++pattern; + } if (*string == '.' && (flags & FNM_PERIOD) && (string == stringstart || @@ -80,7 +85,7 @@ p_fnmatchx(const char *pattern, const char *string, int flags, size_t recurs) while ((test = *string) != EOS) { int e; - e = p_fnmatchx(pattern, string, flags & ~FNM_PERIOD, recurs); + e = p_fnmatchx(pattern, string, recurs_flags, recurs); if (e != FNM_NOMATCH) return e; if (test == '/' && (flags & FNM_PATHNAME)) diff --git a/tests/attr/ignore.c b/tests/attr/ignore.c index 0f945ebf6..692f5e4ba 100644 --- a/tests/attr/ignore.c +++ b/tests/attr/ignore.c @@ -54,6 +54,19 @@ void test_attr_ignore__ignore_root(void) assert_is_ignored(true, "NewFolder/NewFolder/File.txt"); } +void test_attr_ignore__full_paths(void) +{ + cl_git_rewritefile("attr/.gitignore", "Folder/*/Contained"); + + assert_is_ignored(true, "Folder/Middle/Contained"); + assert_is_ignored(false, "Folder/Middle/More/More/Contained"); + + cl_git_rewritefile("attr/.gitignore", "Folder/**/Contained"); + + assert_is_ignored(true, "Folder/Middle/Contained"); + assert_is_ignored(true, "Folder/Middle/More/More/Contained"); +} + void test_attr_ignore__skip_gitignore_directory(void) {