]>
git.proxmox.com Git - libgit2.git/blob - tests/ignore/path.c
a574d1d799d4db5284e6dbcc8c73568a79b7f822
1 #include "clar_libgit2.h"
6 static git_repository
*g_repo
= NULL
;
8 void test_ignore_path__initialize(void)
10 g_repo
= cl_git_sandbox_init("attr");
13 void test_ignore_path__cleanup(void)
15 cl_git_sandbox_cleanup();
19 static void assert_is_ignored_(
20 bool expected
, const char *filepath
,
21 const char *file
, const char *func
, int line
)
26 git_ignore_path_is_ignored(&is_ignored
, g_repo
, filepath
), 0, file
, func
, line
);
29 file
, func
, line
, "expected != is_ignored", 1, "%d",
30 (int)(expected
!= 0), (int)(is_ignored
!= 0));
32 #define assert_is_ignored(expected, filepath) \
33 assert_is_ignored_(expected, filepath, __FILE__, __func__, __LINE__)
35 void test_ignore_path__honor_temporary_rules(void)
37 cl_git_rewritefile("attr/.gitignore", "/NewFolder\n/NewFolder/NewFolder");
39 assert_is_ignored(false, "File.txt");
40 assert_is_ignored(true, "NewFolder");
41 assert_is_ignored(true, "NewFolder/NewFolder");
42 assert_is_ignored(true, "NewFolder/NewFolder/File.txt");
45 void test_ignore_path__allow_root(void)
47 cl_git_rewritefile("attr/.gitignore", "/");
49 assert_is_ignored(false, "File.txt");
50 assert_is_ignored(false, "NewFolder");
51 assert_is_ignored(false, "NewFolder/NewFolder");
52 assert_is_ignored(false, "NewFolder/NewFolder/File.txt");
55 void test_ignore_path__ignore_space(void)
57 cl_git_rewritefile("attr/.gitignore", "/\n\n/NewFolder \n/NewFolder/NewFolder");
59 assert_is_ignored(false, "File.txt");
60 assert_is_ignored(true, "NewFolder");
61 assert_is_ignored(true, "NewFolder/NewFolder");
62 assert_is_ignored(true, "NewFolder/NewFolder/File.txt");
65 void test_ignore_path__intermittent_space(void)
67 cl_git_rewritefile("attr/.gitignore", "foo bar\n");
69 assert_is_ignored(false, "foo");
70 assert_is_ignored(false, "bar");
71 assert_is_ignored(true, "foo bar");
74 void test_ignore_path__trailing_space(void)
82 assert_is_ignored(true, "foo");
83 assert_is_ignored(false, "foo ");
84 assert_is_ignored(true, "bar");
85 assert_is_ignored(false, "bar ");
86 assert_is_ignored(false, "bar ");
89 void test_ignore_path__escaped_trailing_spaces(void)
99 assert_is_ignored(false, "foo");
100 assert_is_ignored(true, "foo ");
101 assert_is_ignored(false, "bar");
102 assert_is_ignored(false, "bar ");
103 assert_is_ignored(true, "bar ");
104 assert_is_ignored(true, "baz ");
105 assert_is_ignored(false, "baz ");
106 assert_is_ignored(true, "qux ");
107 assert_is_ignored(false, "qux");
108 assert_is_ignored(false, "qux ");
111 void test_ignore_path__ignore_dir(void)
113 cl_git_rewritefile("attr/.gitignore", "dir/\n");
115 assert_is_ignored(true, "dir");
116 assert_is_ignored(true, "dir/file");
119 void test_ignore_path__ignore_dir_with_trailing_space(void)
121 cl_git_rewritefile("attr/.gitignore", "dir/ \n");
123 assert_is_ignored(true, "dir");
124 assert_is_ignored(true, "dir/file");
127 void test_ignore_path__ignore_root(void)
129 cl_git_rewritefile("attr/.gitignore", "/\n\n/NewFolder\n/NewFolder/NewFolder");
131 assert_is_ignored(false, "File.txt");
132 assert_is_ignored(true, "NewFolder");
133 assert_is_ignored(true, "NewFolder/NewFolder");
134 assert_is_ignored(true, "NewFolder/NewFolder/File.txt");
137 void test_ignore_path__full_paths(void)
139 cl_git_rewritefile("attr/.gitignore", "Folder/*/Contained");
141 assert_is_ignored(true, "Folder/Middle/Contained");
142 assert_is_ignored(false, "Folder/Middle/More/More/Contained");
144 cl_git_rewritefile("attr/.gitignore", "Folder/**/Contained");
146 assert_is_ignored(true, "Folder/Middle/Contained");
147 assert_is_ignored(true, "Folder/Middle/More/More/Contained");
149 cl_git_rewritefile("attr/.gitignore", "Folder/**/Contained/*/Child");
151 assert_is_ignored(true, "Folder/Middle/Contained/Happy/Child");
152 assert_is_ignored(false, "Folder/Middle/Contained/Not/Happy/Child");
153 assert_is_ignored(true, "Folder/Middle/More/More/Contained/Happy/Child");
154 assert_is_ignored(false, "Folder/Middle/More/More/Contained/Not/Happy/Child");
157 void test_ignore_path__more_starstar_cases(void)
159 cl_must_pass(p_unlink("attr/.gitignore"));
161 "attr/dir/.gitignore",
164 assert_is_ignored(false, "aaa.html");
165 assert_is_ignored(false, "dir");
166 assert_is_ignored(false, "dir/sub");
167 assert_is_ignored(true, "dir/sub/sub2/aaa.html");
168 assert_is_ignored(true, "dir/sub/aaa.html");
169 assert_is_ignored(false, "dir/aaa.html");
170 assert_is_ignored(false, "sub");
171 assert_is_ignored(false, "sub/aaa.html");
172 assert_is_ignored(false, "sub/sub2/aaa.html");
175 void test_ignore_path__leading_stars(void)
182 "**/parent2/kid2/*\n");
184 assert_is_ignored(true, "dir1/onestar");
185 assert_is_ignored(true, "dir1/onestar/child"); /* in ignored dir */
186 assert_is_ignored(false, "dir1/dir2/onestar");
188 assert_is_ignored(true, "dir1/twostars");
189 assert_is_ignored(true, "dir1/twostars/child"); /* in ignored dir */
190 assert_is_ignored(true, "dir1/dir2/twostars");
191 assert_is_ignored(true, "dir1/dir2/twostars/child"); /* in ignored dir */
192 assert_is_ignored(true, "dir1/dir2/dir3/twostars");
194 assert_is_ignored(true, "dir1/parent1/kid1/file");
195 assert_is_ignored(true, "dir1/parent1/kid1/file/inside/parent");
196 assert_is_ignored(false, "dir1/dir2/parent1/kid1/file");
197 assert_is_ignored(false, "dir1/parent1/file");
198 assert_is_ignored(false, "dir1/kid1/file");
200 assert_is_ignored(true, "dir1/parent2/kid2/file");
201 assert_is_ignored(true, "dir1/parent2/kid2/file/inside/parent");
202 assert_is_ignored(true, "dir1/dir2/parent2/kid2/file");
203 assert_is_ignored(true, "dir1/dir2/dir3/parent2/kid2/file");
204 assert_is_ignored(false, "dir1/parent2/file");
205 assert_is_ignored(false, "dir1/kid2/file");
208 void test_ignore_path__globs_and_path_delimiters(void)
210 cl_git_rewritefile("attr/.gitignore", "foo/bar/**");
211 assert_is_ignored(true, "foo/bar/baz");
212 assert_is_ignored(true, "foo/bar/baz/quux");
214 cl_git_rewritefile("attr/.gitignore", "_*/");
215 assert_is_ignored(true, "sub/_test/a/file");
216 assert_is_ignored(false, "test_folder/file");
217 assert_is_ignored(true, "_test/file");
218 assert_is_ignored(true, "_test/a/file");
220 cl_git_rewritefile("attr/.gitignore", "**/_*/");
221 assert_is_ignored(true, "sub/_test/a/file");
222 assert_is_ignored(false, "test_folder/file");
223 assert_is_ignored(true, "_test/file");
224 assert_is_ignored(true, "_test/a/file");
226 cl_git_rewritefile("attr/.gitignore", "**/_*/foo/bar/*ux");
228 assert_is_ignored(true, "sub/_test/foo/bar/qux/file");
229 assert_is_ignored(true, "_test/foo/bar/qux/file");
230 assert_is_ignored(true, "_test/foo/bar/crux/file");
231 assert_is_ignored(false, "_test/foo/bar/code/file");
234 void test_ignore_path__globs_without_star(void)
242 assert_is_ignored(true, ".foo");
243 assert_is_ignored(true, "xyz.foo");
244 assert_is_ignored(true, ".bar");
245 assert_is_ignored(true, "x.bar");
246 assert_is_ignored(true, "xyz.bar");
248 assert_is_ignored(true, "test/.foo");
249 assert_is_ignored(true, "test/x.foo");
250 assert_is_ignored(true, "test/xyz.foo");
251 assert_is_ignored(true, "test/.bar");
252 assert_is_ignored(true, "test/x.bar");
253 assert_is_ignored(true, "test/xyz.bar");
256 void test_ignore_path__skip_gitignore_directory(void)
258 cl_git_rewritefile("attr/.git/info/exclude", "/NewFolder\n/NewFolder/NewFolder");
259 cl_must_pass(p_unlink("attr/.gitignore"));
260 cl_assert(!git_fs_path_exists("attr/.gitignore"));
261 p_mkdir("attr/.gitignore", 0777);
262 cl_git_mkfile("attr/.gitignore/garbage.txt", "new_file\n");
264 assert_is_ignored(false, "File.txt");
265 assert_is_ignored(true, "NewFolder");
266 assert_is_ignored(true, "NewFolder/NewFolder");
267 assert_is_ignored(true, "NewFolder/NewFolder/File.txt");
270 void test_ignore_path__subdirectory_gitignore(void)
272 cl_must_pass(p_unlink("attr/.gitignore"));
273 cl_assert(!git_fs_path_exists("attr/.gitignore"));
278 "attr/dir/.gitignore",
281 assert_is_ignored(true, "file1");
282 assert_is_ignored(true, "dir/file1");
283 assert_is_ignored(true, "dir/file2/actual_file"); /* in ignored dir */
284 assert_is_ignored(false, "dir/file3");
287 void test_ignore_path__expand_tilde_to_homedir(void)
291 assert_is_ignored(false, "example.global_with_tilde");
295 /* construct fake home with fake global excludes */
296 cl_git_mkfile("home/globalexclude", "# found me\n*.global_with_tilde\n");
298 cl_git_pass(git_repository_config(&cfg
, g_repo
));
299 cl_git_pass(git_config_set_string(cfg
, "core.excludesfile", "~/globalexclude"));
300 git_config_free(cfg
);
302 git_attr_cache_flush(g_repo
); /* must reset to pick up change */
304 assert_is_ignored(true, "example.global_with_tilde");
306 cl_git_pass(git_futils_rmdir_r("home", NULL
, GIT_RMDIR_REMOVE_FILES
));
308 cl_fake_home_cleanup(NULL
);
310 git_attr_cache_flush(g_repo
); /* must reset to pick up change */
312 assert_is_ignored(false, "example.global_with_tilde");
315 /* Ensure that the .gitignore in the subdirectory only affects
316 * items in the subdirectory. */
317 void test_ignore_path__gitignore_in_subdir(void)
319 cl_git_rmfile("attr/.gitignore");
321 cl_must_pass(p_mkdir("attr/dir1", 0777));
322 cl_must_pass(p_mkdir("attr/dir1/dir2", 0777));
323 cl_must_pass(p_mkdir("attr/dir1/dir2/dir3", 0777));
325 cl_git_mkfile("attr/dir1/dir2/dir3/.gitignore", "dir1/\ndir1/subdir/");
327 assert_is_ignored(false, "dir1/file");
328 assert_is_ignored(false, "dir1/dir2/file");
329 assert_is_ignored(false, "dir1/dir2/dir3/file");
330 assert_is_ignored(true, "dir1/dir2/dir3/dir1/file");
331 assert_is_ignored(true, "dir1/dir2/dir3/dir1/subdir/foo");
333 if (cl_repo_get_bool(g_repo
, "core.ignorecase")) {
334 cl_git_mkfile("attr/dir1/dir2/dir3/.gitignore", "DiR1/\nDiR1/subdir/\n");
336 assert_is_ignored(false, "dir1/file");
337 assert_is_ignored(false, "dir1/dir2/file");
338 assert_is_ignored(false, "dir1/dir2/dir3/file");
339 assert_is_ignored(true, "dir1/dir2/dir3/dir1/file");
340 assert_is_ignored(true, "dir1/dir2/dir3/dir1/subdir/foo");
344 /* Ensure that files do not match folder cases */
345 void test_ignore_path__dont_ignore_files_for_folder(void)
347 cl_git_rmfile("attr/.gitignore");
349 cl_git_mkfile("attr/dir/.gitignore", "test/\n");
351 /* Create "test" as a file; ensure it is not ignored. */
352 cl_git_mkfile("attr/dir/test", "This is a file.");
354 assert_is_ignored(false, "dir/test");
355 if (cl_repo_get_bool(g_repo
, "core.ignorecase"))
356 assert_is_ignored(false, "dir/TeSt");
358 /* Create "test" as a directory; ensure it is ignored. */
359 cl_git_rmfile("attr/dir/test");
360 cl_must_pass(p_mkdir("attr/dir/test", 0777));
362 assert_is_ignored(true, "dir/test");
363 if (cl_repo_get_bool(g_repo
, "core.ignorecase"))
364 assert_is_ignored(true, "dir/TeSt");
366 /* Remove "test" entirely; ensure it is not ignored.
367 * (As it doesn't exist, it is not a directory.)
369 cl_must_pass(p_rmdir("attr/dir/test"));
371 assert_is_ignored(false, "dir/test");
372 if (cl_repo_get_bool(g_repo
, "core.ignorecase"))
373 assert_is_ignored(false, "dir/TeSt");
376 void test_ignore_path__symlink_to_outside(void)
382 cl_git_rewritefile("attr/.gitignore", "symlink\n");
383 cl_git_mkfile("target", "target");
384 cl_git_pass(p_symlink("../target", "attr/symlink"));
385 assert_is_ignored(true, "symlink");
386 assert_is_ignored(true, "lala/../symlink");
389 void test_ignore_path__test(void)
391 cl_git_rewritefile("attr/.gitignore",
394 assert_is_ignored(false, "src/foo.c");
395 assert_is_ignored(false, "src/foo/foo.c");
396 assert_is_ignored(false, "README.md");
397 assert_is_ignored(true, "dist/foo.o");
398 assert_is_ignored(true, "bin/foo");
401 void test_ignore_path__unignore_dir_succeeds(void)
403 cl_git_rewritefile("attr/.gitignore",
406 assert_is_ignored(false, "src/foo.c");
407 assert_is_ignored(true, "src/foo/foo.c");
410 void test_ignore_path__case_insensitive_unignores_previous_rule(void)
414 cl_git_rewritefile("attr/.gitignore",
418 cl_git_pass(git_repository_config(&cfg
, g_repo
));
419 cl_git_pass(git_config_set_bool(cfg
, "core.ignorecase", true));
421 cl_must_pass(p_mkdir("attr/case", 0755));
422 cl_git_mkfile("attr/case/file", "content");
424 assert_is_ignored(false, "case/file");
427 void test_ignore_path__case_sensitive_unignore_does_nothing(void)
431 cl_git_rewritefile("attr/.gitignore",
435 cl_git_pass(git_repository_config(&cfg
, g_repo
));
436 cl_git_pass(git_config_set_bool(cfg
, "core.ignorecase", false));
438 cl_must_pass(p_mkdir("attr/case", 0755));
439 cl_git_mkfile("attr/case/file", "content");
441 assert_is_ignored(true, "case/file");
444 void test_ignore_path__ignored_subdirfiles_with_subdir_rule(void)
449 "!dir/sub1/sub2/**\n");
451 assert_is_ignored(true, "dir/a.test");
452 assert_is_ignored(true, "dir/sub1/a.test");
453 assert_is_ignored(true, "dir/sub1/sub2");
456 void test_ignore_path__ignored_subdirfiles_with_negations(void)
463 assert_is_ignored(false, "dir/a.test");
464 assert_is_ignored(true, "dir/b.test");
465 assert_is_ignored(true, "dir/sub1/c.test");
468 void test_ignore_path__negative_directory_rules_only_match_directories(void)
478 assert_is_ignored(true, "src");
479 assert_is_ignored(true, "src/A");
480 assert_is_ignored(false, "src/");
481 assert_is_ignored(false, "src/A.keep");
482 assert_is_ignored(false, ".gitignore");
485 void test_ignore_path__escaped_character(void)
487 cl_git_rewritefile("attr/.gitignore", "\\c\n");
488 assert_is_ignored(true, "c");
489 assert_is_ignored(false, "\\c");
492 void test_ignore_path__escaped_newline(void)
499 assert_is_ignored(true, "\nnewline");
502 void test_ignore_path__escaped_glob(void)
504 cl_git_rewritefile("attr/.gitignore", "\\*\n");
505 assert_is_ignored(true, "*");
506 assert_is_ignored(false, "foo");
509 void test_ignore_path__escaped_comments(void)
519 assert_is_ignored(false, "#foo");
520 assert_is_ignored(true, "#bar");
521 assert_is_ignored(false, "\\#bar");
522 assert_is_ignored(true, "##baz");
523 assert_is_ignored(false, "\\##baz");
524 assert_is_ignored(true, "#\\#qux");
525 assert_is_ignored(false, "##qux");
526 assert_is_ignored(false, "\\##qux");
529 void test_ignore_path__escaped_slash(void)
540 assert_is_ignored(true, "\\");
541 assert_is_ignored(true, "\\preceding");
543 assert_is_ignored(true, "inter\\mittent");
544 assert_is_ignored(true, "trailing\\");
547 void test_ignore_path__escaped_space(void)
553 assert_is_ignored(true, "foo\\");
554 assert_is_ignored(false, "foo\\ ");
555 assert_is_ignored(false, "foo\\\\ ");
556 assert_is_ignored(false, "foo\\\\");
557 assert_is_ignored(true, "bar\\ ");
558 assert_is_ignored(false, "bar\\\\");
559 assert_is_ignored(false, "bar\\\\ ");
560 assert_is_ignored(false, "bar\\\\\\");
561 assert_is_ignored(false, "bar\\\\\\ ");
564 void test_ignore_path__invalid_pattern(void)
566 cl_git_rewritefile("attr/.gitignore", "[");
567 assert_is_ignored(false, "[f");
568 assert_is_ignored(false, "f");
571 void test_ignore_path__negative_prefix_rule(void)
573 cl_git_rewritefile("attr/.gitignore", "ff*\n!f\n");
574 assert_is_ignored(true, "fff");
575 assert_is_ignored(true, "ff");
576 assert_is_ignored(false, "f");
579 void test_ignore_path__negative_more_specific(void)
581 cl_git_rewritefile("attr/.gitignore", "*.txt\n!/dir/test.txt\n");
582 assert_is_ignored(true, "test.txt");
583 assert_is_ignored(false, "dir/test.txt");
584 assert_is_ignored(true, "outer/dir/test.txt");