summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2014-04-04 17:02:12 -0700
committerRussell Belfer <rb@github.com>2014-04-04 17:02:12 -0700
commit2b6b85f1168206f6f53144b9c98ecc4ce2e74a88 (patch)
tree3b012be7c233676ad8b9ab8c03fed1b25f806cdd
parent923c84008d6e3a4bf36ce08f9145a11b90f27185 (diff)
downloadlibgit2-2b6b85f1168206f6f53144b9c98ecc4ce2e74a88.tar.gz
Add support for ** matches in ignores
This is an experimental addition to add ** support to fnmatch pattern matching in libgit2. It needs more testing.
-rw-r--r--src/fnmatch.c11
-rw-r--r--tests/attr/ignore.c13
2 files changed, 21 insertions, 3 deletions
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)
{