]> git.proxmox.com Git - libgit2.git/blame - tests/attr/ignore.c
New upstream version 0.28.4+dfsg.1
[libgit2.git] / tests / attr / ignore.c
CommitLineData
d788499a 1#include "clar_libgit2.h"
37d91686
RB
2#include "posix.h"
3#include "path.h"
7a5ee3dc 4#include "fileops.h"
d788499a 5
6static git_repository *g_repo = NULL;
7
8void test_attr_ignore__initialize(void)
9{
37d91686 10 g_repo = cl_git_sandbox_init("attr");
d788499a 11}
12
13void test_attr_ignore__cleanup(void)
14{
37d91686
RB
15 cl_git_sandbox_cleanup();
16 g_repo = NULL;
d788499a 17}
18
50e46d60 19static void assert_is_ignored_(
c8c91433 20 bool expected, const char *filepath, const char *file, int line)
d788499a 21{
c8c91433 22 int is_ignored = 0;
d788499a 23
c52480fd 24 cl_git_expect(
a1dcc830 25 git_ignore_path_is_ignored(&is_ignored, g_repo, filepath), 0, file, line);
c8c91433
RB
26
27 clar__assert_equal(
28 file, line, "expected != is_ignored", 1, "%d",
29 (int)(expected != 0), (int)(is_ignored != 0));
d788499a 30}
c8c91433
RB
31#define assert_is_ignored(expected, filepath) \
32 assert_is_ignored_(expected, filepath, __FILE__, __LINE__)
d788499a 33
34void test_attr_ignore__honor_temporary_rules(void)
35{
37d91686 36 cl_git_rewritefile("attr/.gitignore", "/NewFolder\n/NewFolder/NewFolder");
d788499a 37
37d91686
RB
38 assert_is_ignored(false, "File.txt");
39 assert_is_ignored(true, "NewFolder");
40 assert_is_ignored(true, "NewFolder/NewFolder");
41 assert_is_ignored(true, "NewFolder/NewFolder/File.txt");
42}
43
2d160ef7
ET
44void test_attr_ignore__allow_root(void)
45{
46 cl_git_rewritefile("attr/.gitignore", "/");
47
48 assert_is_ignored(false, "File.txt");
49 assert_is_ignored(false, "NewFolder");
50 assert_is_ignored(false, "NewFolder/NewFolder");
51 assert_is_ignored(false, "NewFolder/NewFolder/File.txt");
52}
53
eae0bfdc
PP
54void test_attr_ignore__ignore_space(void)
55{
56 cl_git_rewritefile("attr/.gitignore", "/\n\n/NewFolder \n/NewFolder/NewFolder");
57
58 assert_is_ignored(false, "File.txt");
59 assert_is_ignored(true, "NewFolder");
60 assert_is_ignored(true, "NewFolder/NewFolder");
61 assert_is_ignored(true, "NewFolder/NewFolder/File.txt");
62}
63
4b3ec53c
XL
64void test_attr_ignore__ignore_dir(void)
65{
66 cl_git_rewritefile("attr/.gitignore", "dir/\n");
67
68 assert_is_ignored(true, "dir");
69 assert_is_ignored(true, "dir/file");
70}
71
72void test_attr_ignore__ignore_dir_with_trailing_space(void)
73{
74 cl_git_rewritefile("attr/.gitignore", "dir/ \n");
75
76 assert_is_ignored(true, "dir");
77 assert_is_ignored(true, "dir/file");
78}
79
2d160ef7
ET
80void test_attr_ignore__ignore_root(void)
81{
82 cl_git_rewritefile("attr/.gitignore", "/\n\n/NewFolder\n/NewFolder/NewFolder");
83
84 assert_is_ignored(false, "File.txt");
85 assert_is_ignored(true, "NewFolder");
86 assert_is_ignored(true, "NewFolder/NewFolder");
87 assert_is_ignored(true, "NewFolder/NewFolder/File.txt");
88}
89
2b6b85f1
RB
90void test_attr_ignore__full_paths(void)
91{
92 cl_git_rewritefile("attr/.gitignore", "Folder/*/Contained");
93
94 assert_is_ignored(true, "Folder/Middle/Contained");
95 assert_is_ignored(false, "Folder/Middle/More/More/Contained");
96
97 cl_git_rewritefile("attr/.gitignore", "Folder/**/Contained");
98
99 assert_is_ignored(true, "Folder/Middle/Contained");
100 assert_is_ignored(true, "Folder/Middle/More/More/Contained");
c8c91433
RB
101
102 cl_git_rewritefile("attr/.gitignore", "Folder/**/Contained/*/Child");
103
104 assert_is_ignored(true, "Folder/Middle/Contained/Happy/Child");
105 assert_is_ignored(false, "Folder/Middle/Contained/Not/Happy/Child");
106 assert_is_ignored(true, "Folder/Middle/More/More/Contained/Happy/Child");
107 assert_is_ignored(false, "Folder/Middle/More/More/Contained/Not/Happy/Child");
2b6b85f1
RB
108}
109
d19b2f9f
RB
110void test_attr_ignore__more_starstar_cases(void)
111{
112 cl_must_pass(p_unlink("attr/.gitignore"));
113 cl_git_mkfile(
114 "attr/dir/.gitignore",
115 "sub/**/*.html\n");
116
117 assert_is_ignored(false, "aaa.html");
118 assert_is_ignored(false, "dir");
119 assert_is_ignored(false, "dir/sub");
120 assert_is_ignored(true, "dir/sub/sub2/aaa.html");
121 assert_is_ignored(true, "dir/sub/aaa.html");
122 assert_is_ignored(false, "dir/aaa.html");
123 assert_is_ignored(false, "sub");
124 assert_is_ignored(false, "sub/aaa.html");
125 assert_is_ignored(false, "sub/sub2/aaa.html");
126}
127
c8c91433
RB
128void test_attr_ignore__leading_stars(void)
129{
130 cl_git_rewritefile(
131 "attr/.gitignore",
132 "*/onestar\n"
133 "**/twostars\n"
134 "*/parent1/kid1/*\n"
135 "**/parent2/kid2/*\n");
136
137 assert_is_ignored(true, "dir1/onestar");
138 assert_is_ignored(true, "dir1/onestar/child"); /* in ignored dir */
139 assert_is_ignored(false, "dir1/dir2/onestar");
140
141 assert_is_ignored(true, "dir1/twostars");
142 assert_is_ignored(true, "dir1/twostars/child"); /* in ignored dir */
143 assert_is_ignored(true, "dir1/dir2/twostars");
144 assert_is_ignored(true, "dir1/dir2/twostars/child"); /* in ignored dir */
145 assert_is_ignored(true, "dir1/dir2/dir3/twostars");
146
147 assert_is_ignored(true, "dir1/parent1/kid1/file");
148 assert_is_ignored(true, "dir1/parent1/kid1/file/inside/parent");
149 assert_is_ignored(false, "dir1/dir2/parent1/kid1/file");
150 assert_is_ignored(false, "dir1/parent1/file");
151 assert_is_ignored(false, "dir1/kid1/file");
152
153 assert_is_ignored(true, "dir1/parent2/kid2/file");
154 assert_is_ignored(true, "dir1/parent2/kid2/file/inside/parent");
155 assert_is_ignored(true, "dir1/dir2/parent2/kid2/file");
156 assert_is_ignored(true, "dir1/dir2/dir3/parent2/kid2/file");
157 assert_is_ignored(false, "dir1/parent2/file");
158 assert_is_ignored(false, "dir1/kid2/file");
159}
2d160ef7 160
0f362716
AS
161void test_attr_ignore__globs_and_path_delimiters(void)
162{
1c3018eb
CMN
163 cl_git_rewritefile("attr/.gitignore", "foo/bar/**");
164 assert_is_ignored(true, "foo/bar/baz");
165 assert_is_ignored(true, "foo/bar/baz/quux");
166
167 cl_git_rewritefile("attr/.gitignore", "_*/");
168 assert_is_ignored(true, "sub/_test/a/file");
169 assert_is_ignored(false, "test_folder/file");
170 assert_is_ignored(true, "_test/file");
171 assert_is_ignored(true, "_test/a/file");
172
0f362716 173 cl_git_rewritefile("attr/.gitignore", "**/_*/");
1c3018eb 174 assert_is_ignored(true, "sub/_test/a/file");
0f362716
AS
175 assert_is_ignored(false, "test_folder/file");
176 assert_is_ignored(true, "_test/file");
177 assert_is_ignored(true, "_test/a/file");
178
179 cl_git_rewritefile("attr/.gitignore", "**/_*/foo/bar/*ux");
180
1c3018eb 181 assert_is_ignored(true, "sub/_test/foo/bar/qux/file");
0f362716
AS
182 assert_is_ignored(true, "_test/foo/bar/qux/file");
183 assert_is_ignored(true, "_test/foo/bar/crux/file");
184 assert_is_ignored(false, "_test/foo/bar/code/file");
185}
186
37d91686
RB
187void test_attr_ignore__skip_gitignore_directory(void)
188{
189 cl_git_rewritefile("attr/.git/info/exclude", "/NewFolder\n/NewFolder/NewFolder");
190 p_unlink("attr/.gitignore");
191 cl_assert(!git_path_exists("attr/.gitignore"));
192 p_mkdir("attr/.gitignore", 0777);
193 cl_git_mkfile("attr/.gitignore/garbage.txt", "new_file\n");
194
195 assert_is_ignored(false, "File.txt");
196 assert_is_ignored(true, "NewFolder");
197 assert_is_ignored(true, "NewFolder/NewFolder");
198 assert_is_ignored(true, "NewFolder/NewFolder/File.txt");
d788499a 199}
7a5ee3dc 200
c6bf03b4
MM
201void test_attr_ignore__subdirectory_gitignore(void)
202{
203 p_unlink("attr/.gitignore");
204 cl_assert(!git_path_exists("attr/.gitignore"));
205 cl_git_mkfile(
206 "attr/.gitignore",
207 "file1\n");
208 p_mkdir("attr/dir", 0777);
209 cl_git_mkfile(
210 "attr/dir/.gitignore",
211 "file2/\n");
212
213 assert_is_ignored(true, "file1");
214 assert_is_ignored(true, "dir/file1");
9486d203 215 assert_is_ignored(true, "dir/file2/actual_file"); /* in ignored dir */
c6bf03b4
MM
216 assert_is_ignored(false, "dir/file3");
217}
218
7a5ee3dc
RB
219void test_attr_ignore__expand_tilde_to_homedir(void)
220{
7a5ee3dc
RB
221 git_config *cfg;
222
223 assert_is_ignored(false, "example.global_with_tilde");
224
0f603132 225 cl_fake_home();
7a5ee3dc 226
a9528b8f
RB
227 /* construct fake home with fake global excludes */
228 cl_git_mkfile("home/globalexclude", "# found me\n*.global_with_tilde\n");
7a5ee3dc
RB
229
230 cl_git_pass(git_repository_config(&cfg, g_repo));
a9528b8f 231 cl_git_pass(git_config_set_string(cfg, "core.excludesfile", "~/globalexclude"));
7a5ee3dc
RB
232 git_config_free(cfg);
233
234 git_attr_cache_flush(g_repo); /* must reset to pick up change */
235
236 assert_is_ignored(true, "example.global_with_tilde");
237
238 cl_git_pass(git_futils_rmdir_r("home", NULL, GIT_RMDIR_REMOVE_FILES));
239
0f603132 240 cl_fake_home_cleanup(NULL);
7a5ee3dc 241
a9528b8f
RB
242 git_attr_cache_flush(g_repo); /* must reset to pick up change */
243
244 assert_is_ignored(false, "example.global_with_tilde");
7a5ee3dc 245}
adad5181
ET
246
247/* Ensure that the .gitignore in the subdirectory only affects
248 * items in the subdirectory. */
249void test_attr_ignore__gitignore_in_subdir(void)
250{
251 cl_git_rmfile("attr/.gitignore");
252
253 cl_must_pass(p_mkdir("attr/dir1", 0777));
254 cl_must_pass(p_mkdir("attr/dir1/dir2", 0777));
255 cl_must_pass(p_mkdir("attr/dir1/dir2/dir3", 0777));
256
257 cl_git_mkfile("attr/dir1/dir2/dir3/.gitignore", "dir1/\ndir1/subdir/");
258
259 assert_is_ignored(false, "dir1/file");
260 assert_is_ignored(false, "dir1/dir2/file");
261 assert_is_ignored(false, "dir1/dir2/dir3/file");
adad5181
ET
262 assert_is_ignored(true, "dir1/dir2/dir3/dir1/file");
263 assert_is_ignored(true, "dir1/dir2/dir3/dir1/subdir/foo");
264
265 if (cl_repo_get_bool(g_repo, "core.ignorecase")) {
266 cl_git_mkfile("attr/dir1/dir2/dir3/.gitignore", "DiR1/\nDiR1/subdir/\n");
267
268 assert_is_ignored(false, "dir1/file");
269 assert_is_ignored(false, "dir1/dir2/file");
270 assert_is_ignored(false, "dir1/dir2/dir3/file");
adad5181
ET
271 assert_is_ignored(true, "dir1/dir2/dir3/dir1/file");
272 assert_is_ignored(true, "dir1/dir2/dir3/dir1/subdir/foo");
273 }
274}
275
882cc37f
ET
276/* Ensure that files do not match folder cases */
277void test_attr_ignore__dont_ignore_files_for_folder(void)
97fb9ac7
ET
278{
279 cl_git_rmfile("attr/.gitignore");
280
882cc37f 281 cl_git_mkfile("attr/dir/.gitignore", "test/\n");
97fb9ac7 282
882cc37f
ET
283 /* Create "test" as a file; ensure it is not ignored. */
284 cl_git_mkfile("attr/dir/test", "This is a file.");
97fb9ac7 285
882cc37f
ET
286 assert_is_ignored(false, "dir/test");
287 if (cl_repo_get_bool(g_repo, "core.ignorecase"))
288 assert_is_ignored(false, "dir/TeSt");
97fb9ac7 289
882cc37f
ET
290 /* Create "test" as a directory; ensure it is ignored. */
291 cl_git_rmfile("attr/dir/test");
292 cl_must_pass(p_mkdir("attr/dir/test", 0777));
293
294 assert_is_ignored(true, "dir/test");
295 if (cl_repo_get_bool(g_repo, "core.ignorecase"))
296 assert_is_ignored(true, "dir/TeSt");
97fb9ac7 297
882cc37f
ET
298 /* Remove "test" entirely; ensure it is not ignored.
299 * (As it doesn't exist, it is not a directory.)
300 */
301 cl_must_pass(p_rmdir("attr/dir/test"));
302
303 assert_is_ignored(false, "dir/test");
304 if (cl_repo_get_bool(g_repo, "core.ignorecase"))
305 assert_is_ignored(false, "dir/TeSt");
306}
d364dc8b
CMN
307
308void test_attr_ignore__symlink_to_outside(void)
309{
310#ifdef GIT_WIN32
311 cl_skip();
312#endif
313
314 cl_git_rewritefile("attr/.gitignore", "symlink\n");
315 cl_git_mkfile("target", "target");
316 cl_git_pass(p_symlink("../target", "attr/symlink"));
317 assert_is_ignored(true, "symlink");
318 assert_is_ignored(true, "lala/../symlink");
319}
c3b8e8b3
RG
320
321void test_attr_ignore__test(void)
322{
323 cl_git_rewritefile("attr/.gitignore",
324 "/*/\n"
325 "!/src\n");
326 assert_is_ignored(false, "src/foo.c");
327 assert_is_ignored(false, "src/foo/foo.c");
328 assert_is_ignored(false, "README.md");
329 assert_is_ignored(true, "dist/foo.o");
330 assert_is_ignored(true, "bin/foo");
331}
eae0bfdc
PP
332
333void test_attr_ignore__unignore_dir_succeeds(void)
334{
335 cl_git_rewritefile("attr/.gitignore",
336 "*.c\n"
337 "!src/*.c\n");
338 assert_is_ignored(false, "src/foo.c");
339 assert_is_ignored(true, "src/foo/foo.c");
340}
341
342void test_attr_ignore__case_insensitive_unignores_previous_rule(void)
343{
344 git_config *cfg;
345
346 cl_git_rewritefile("attr/.gitignore",
347 "/case\n"
348 "!/Case/\n");
349
350 cl_git_pass(git_repository_config(&cfg, g_repo));
351 cl_git_pass(git_config_set_bool(cfg, "core.ignorecase", true));
352
353 cl_must_pass(p_mkdir("attr/case", 0755));
354 cl_git_mkfile("attr/case/file", "content");
355
356 assert_is_ignored(false, "case/file");
357}
358
359void test_attr_ignore__case_sensitive_unignore_does_nothing(void)
360{
361 git_config *cfg;
362
363 cl_git_rewritefile("attr/.gitignore",
364 "/case\n"
365 "!/Case/\n");
366
367 cl_git_pass(git_repository_config(&cfg, g_repo));
368 cl_git_pass(git_config_set_bool(cfg, "core.ignorecase", false));
369
370 cl_must_pass(p_mkdir("attr/case", 0755));
371 cl_git_mkfile("attr/case/file", "content");
372
373 assert_is_ignored(true, "case/file");
374}
6147f643
PP
375
376void test_attr_ignore__ignored_subdirfiles_with_subdir_rule(void)
377{
378 cl_git_rewritefile(
379 "attr/.gitignore",
380 "dir/*\n"
381 "!dir/sub1/sub2/**\n");
382
383 assert_is_ignored(true, "dir/a.test");
384 assert_is_ignored(true, "dir/sub1/a.test");
385 assert_is_ignored(true, "dir/sub1/sub2");
386}
387
388void test_attr_ignore__ignored_subdirfiles_with_negations(void)
389{
390 cl_git_rewritefile(
391 "attr/.gitignore",
392 "dir/*\n"
393 "!dir/a.test\n");
394
395 assert_is_ignored(false, "dir/a.test");
396 assert_is_ignored(true, "dir/b.test");
397 assert_is_ignored(true, "dir/sub1/c.test");
398}
399
400void test_attr_ignore__negative_directory_rules_only_match_directories(void)
401{
402 cl_git_rewritefile(
403 "attr/.gitignore",
404 "*\n"
405 "!/**/\n"
406 "!*.keep\n"
407 "!.gitignore\n"
408 );
409
410 assert_is_ignored(true, "src");
411 assert_is_ignored(true, "src/A");
412 assert_is_ignored(false, "src/");
413 assert_is_ignored(false, "src/A.keep");
414 assert_is_ignored(false, ".gitignore");
415}