Commit 657afd359e0e49627addb092c05ddd00117614de

Carlos Martín Nieto 2015-09-13T06:18:49

ignore: add test and adjust style and comment for dir with wildmatch The previous commit left the comment referencing the earlier state of the code, change it to explain the current logic. While here, change the logic to avoid repeating the copy of the base pattern.

diff --git a/src/ignore.c b/src/ignore.c
index 1f33687..aedc140 100644
--- a/src/ignore.c
+++ b/src/ignore.c
@@ -89,18 +89,20 @@ static int does_negate_rule(int *out, git_vector *rules, git_attr_fnmatch *match
 		}
 
 	/*
-	 * If we're dealing with a directory (which we know via the
-	 * strchr() check) we want to use 'dirname/<star>' as the
-	 * pattern so p_fnmatch() honours FNM_PATHNAME
+	 * When dealing with a directory, we add '/<star>' so
+	 * p_fnmatch() honours FNM_PATHNAME. Checking for LEADINGDIR
+	 * alone isn't enough as that's also set for nagations, so we
+	 * need to check that NEGATIVE is off.
 	 */
 		git_buf_clear(&buf);
 		if (rule->containing_dir) {
 			git_buf_puts(&buf, rule->containing_dir);
 		}
-		if (rule->flags & GIT_ATTR_FNMATCH_LEADINGDIR && !(rule->flags & GIT_ATTR_FNMATCH_NEGATIVE))
-			error = git_buf_printf(&buf, "%s/*", rule->pattern);
-		else
-			error = git_buf_puts(&buf, rule->pattern);
+
+		error = git_buf_puts(&buf, rule->pattern);
+
+		if ((rule->flags & (GIT_ATTR_FNMATCH_LEADINGDIR | GIT_ATTR_FNMATCH_NEGATIVE)) == GIT_ATTR_FNMATCH_LEADINGDIR)
+			error = git_buf_PUTS(&buf, "/*");
 
 		if (error < 0)
 			goto out;
diff --git a/tests/status/ignore.c b/tests/status/ignore.c
index ba1d69a..bbf8f49 100644
--- a/tests/status/ignore.c
+++ b/tests/status/ignore.c
@@ -1022,3 +1022,20 @@ void test_status_ignore__negate_exact_previous(void)
 	cl_git_pass(git_ignore_path_is_ignored(&ignored, g_repo, ".buildpath"));
 	cl_assert_equal_i(1, ignored);
 }
+
+void test_status_ignore__negate_starstar(void)
+{
+    int ignored;
+
+    g_repo = cl_git_sandbox_init("empty_standard_repo");
+
+    cl_git_mkfile("empty_standard_repo/.gitignore",
+              "code/projects/**/packages/*\n"
+              "!code/projects/**/packages/repositories.config");
+
+    cl_git_pass(git_futils_mkdir_r("code/projects/foo/bar/packages", "empty_standard_repo", 0777));
+    cl_git_mkfile("empty_standard_repo/code/projects/foo/bar/packages/repositories.config", "");
+
+    cl_git_pass(git_ignore_path_is_ignored(&ignored, g_repo, "code/projects/foo/bar/packages/repositories.config"));
+    cl_assert_equal_i(0, ignored);
+}