Commit bbe13802b7f85343d3db1aeb799662ee11461e6b

Rob Rix 2014-06-12T14:19:34

Demonstrate a trailing slash failure. `git help ignore` has this to say about trailing slashes: > If the pattern ends with a slash, it is removed for the purpose of > the following description, but it would only find a match with a > directory. In other words, foo/ will match a directory foo and > paths underneath it, but will not match a regular file or a > symbolic link foo (this is consistent with the way how pathspec > works in general in Git). Sure enough, having manually performed the same steps as this test, `git status` tells us the following: # On branch master # # Initial commit # # Changes to be committed: # (use "git rm --cached <file>..." to unstage) # # new file: force.txt # # Untracked files: # (use "git add <file>..." to include in what will be committed) # # ../.gitignore # child1/ # child2/ i.e. neither child1 nor child2 is ignored.

diff --git a/tests/status/ignore.c b/tests/status/ignore.c
index 88575ce..b2af790 100644
--- a/tests/status/ignore.c
+++ b/tests/status/ignore.c
@@ -826,3 +826,60 @@ void test_status_ignore__negative_ignores_in_slash_star(void)
 	cl_assert(found_look_ma);
 	cl_assert(found_what_about);
 }
+
+void test_status_ignore__negative_ignores_without_trailing_slash_inside_ignores(void)
+{
+	git_status_options status_opts = GIT_STATUS_OPTIONS_INIT;
+	git_status_list *list;
+	int found_parent_file = 0, found_parent_child1_file = 0, found_parent_child2_file = 0;
+	size_t i;
+	static const char *test_files[] = {
+		"empty_standard_repo/parent/file.txt",
+		"empty_standard_repo/parent/force.txt",
+		"empty_standard_repo/parent/child1/file.txt",
+		"empty_standard_repo/parent/child2/file.txt",
+		NULL
+	};
+
+	make_test_data("empty_standard_repo", test_files);
+	cl_git_mkfile(
+		"empty_standard_repo/.gitignore",
+		"parent/*\n"
+		"!parent/force.txt\n"
+		"!parent/child1\n"
+		"!parent/child2/\n");
+
+	add_one_to_index("parent/force.txt");
+
+	assert_is_ignored("parent/file.txt");
+	refute_is_ignored("parent/force.txt");
+	refute_is_ignored("parent/child1/file.txt");
+	refute_is_ignored("parent/child2/file.txt");
+
+	status_opts.flags = GIT_STATUS_OPT_DEFAULTS;
+	cl_git_pass(git_status_list_new(&list, g_repo, &status_opts));
+	for (i = 0; i < git_status_list_entrycount(list); i++) {
+		const git_status_entry *entry = git_status_byindex(list, i);
+
+		if (!entry->index_to_workdir)
+			continue;
+
+		if (!strcmp("parent/file.txt", entry->index_to_workdir->new_file.path))
+			found_parent_file = 1;
+
+		if (!strcmp("parent/force.txt", entry->index_to_workdir->new_file.path))
+			found_parent_file = 1;
+
+		if (!strcmp("parent/child1/file.txt", entry->index_to_workdir->new_file.path))
+			found_parent_child1_file = 1;
+
+		if (!strcmp("parent/child2/file.txt", entry->index_to_workdir->new_file.path))
+			found_parent_child2_file = 1;
+	}
+	git_status_list_free(list);
+
+	cl_assert(found_parent_file);
+	cl_assert(found_parent_child1_file);
+	cl_assert(found_parent_child2_file);
+}
+