1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 package org.eclipse.jgit.ignore;
44
45 import static java.nio.charset.StandardCharsets.UTF_8;
46 import static org.eclipse.jgit.junit.Assert.assertEquals;
47 import static org.junit.Assert.assertEquals;
48 import static org.junit.Assert.assertFalse;
49 import static org.junit.Assert.assertNotNull;
50 import static org.junit.Assert.assertTrue;
51
52 import java.io.ByteArrayInputStream;
53 import java.io.File;
54 import java.io.IOException;
55 import java.io.InputStream;
56 import java.util.ArrayList;
57 import java.util.Arrays;
58
59 import org.eclipse.jgit.junit.RepositoryTestCase;
60 import org.eclipse.jgit.lib.FileMode;
61 import org.eclipse.jgit.treewalk.FileTreeIterator;
62 import org.eclipse.jgit.treewalk.TreeWalk;
63 import org.eclipse.jgit.treewalk.WorkingTreeIterator;
64 import org.eclipse.jgit.util.FileUtils;
65 import org.eclipse.jgit.util.SystemReader;
66 import org.junit.Test;
67
68
69
70
71 public class IgnoreNodeTest extends RepositoryTestCase {
72 private static final FileMode D = FileMode.TREE;
73
74 private static final FileMode F = FileMode.REGULAR_FILE;
75
76 private static final boolean ignored = true;
77
78 private static final boolean tracked = false;
79
80 private TreeWalk walk;
81
82 @Test
83 public void testSimpleRootGitIgnoreGlobalIgnore() throws IOException {
84 writeIgnoreFile(".gitignore", "x");
85
86 writeTrashFile("a/x/file", "");
87 writeTrashFile("b/x", "");
88 writeTrashFile("x/file", "");
89
90 beginWalk();
91 assertEntry(F, tracked, ".gitignore");
92 assertEntry(D, tracked, "a");
93 assertEntry(D, ignored, "a/x");
94 assertEntry(F, ignored, "a/x/file");
95 assertEntry(D, tracked, "b");
96 assertEntry(F, ignored, "b/x");
97 assertEntry(D, ignored, "x");
98 assertEntry(F, ignored, "x/file");
99 endWalk();
100 }
101
102 @Test
103 public void testSimpleRootGitIgnoreGlobalDirIgnore() throws IOException {
104 writeIgnoreFile(".gitignore", "x/");
105
106 writeTrashFile("a/x/file", "");
107 writeTrashFile("x/file", "");
108
109 beginWalk();
110 assertEntry(F, tracked, ".gitignore");
111 assertEntry(D, tracked, "a");
112 assertEntry(D, ignored, "a/x");
113 assertEntry(F, ignored, "a/x/file");
114 assertEntry(D, ignored, "x");
115 assertEntry(F, ignored, "x/file");
116 endWalk();
117 }
118
119 @Test
120 public void testSimpleRootGitIgnoreWildMatcher() throws IOException {
121 writeIgnoreFile(".gitignore", "**");
122
123 writeTrashFile("a/x", "");
124 writeTrashFile("y", "");
125
126 beginWalk();
127 assertEntry(F, ignored, ".gitignore");
128 assertEntry(D, ignored, "a");
129 assertEntry(F, ignored, "a/x");
130 assertEntry(F, ignored, "y");
131 endWalk();
132 }
133
134 @Test
135 public void testSimpleRootGitIgnoreWildMatcherDirOnly() throws IOException {
136 writeIgnoreFile(".gitignore", "**/");
137
138 writeTrashFile("a/x", "");
139 writeTrashFile("y", "");
140
141 beginWalk();
142 assertEntry(F, tracked, ".gitignore");
143 assertEntry(D, ignored, "a");
144 assertEntry(F, ignored, "a/x");
145 assertEntry(F, tracked, "y");
146 endWalk();
147 }
148
149 @Test
150 public void testSimpleRootGitIgnoreGlobalNegation1() throws IOException {
151 writeIgnoreFile(".gitignore", "*", "!x*");
152 writeTrashFile("x1", "");
153 writeTrashFile("a/x2", "");
154 writeTrashFile("x3/y", "");
155
156 beginWalk();
157 assertEntry(F, ignored, ".gitignore");
158 assertEntry(D, ignored, "a");
159 assertEntry(F, ignored, "a/x2");
160 assertEntry(F, tracked, "x1");
161 assertEntry(D, tracked, "x3");
162 assertEntry(F, ignored, "x3/y");
163 endWalk();
164 }
165
166 @Test
167 public void testSimpleRootGitIgnoreGlobalNegation2() throws IOException {
168 writeIgnoreFile(".gitignore", "*", "!x*", "!/a");
169 writeTrashFile("x1", "");
170 writeTrashFile("a/x2", "");
171 writeTrashFile("x3/y", "");
172
173 beginWalk();
174 assertEntry(F, ignored, ".gitignore");
175 assertEntry(D, tracked, "a");
176 assertEntry(F, tracked, "a/x2");
177 assertEntry(F, tracked, "x1");
178 assertEntry(D, tracked, "x3");
179 assertEntry(F, ignored, "x3/y");
180 endWalk();
181 }
182
183 @Test
184 public void testSimpleRootGitIgnoreGlobalNegation3() throws IOException {
185 writeIgnoreFile(".gitignore", "*", "!x*", "!x*/**");
186 writeTrashFile("x1", "");
187 writeTrashFile("a/x2", "");
188 writeTrashFile("x3/y", "");
189
190 beginWalk();
191 assertEntry(F, ignored, ".gitignore");
192 assertEntry(D, ignored, "a");
193 assertEntry(F, ignored, "a/x2");
194 assertEntry(F, tracked, "x1");
195 assertEntry(D, tracked, "x3");
196 assertEntry(F, tracked, "x3/y");
197 endWalk();
198 }
199
200 @Test
201 public void testSimpleRootGitIgnoreGlobalNegation4() throws IOException {
202 writeIgnoreFile(".gitignore", "*", "!**/");
203 writeTrashFile("x1", "");
204 writeTrashFile("a/x2", "");
205 writeTrashFile("x3/y", "");
206
207 beginWalk();
208 assertEntry(F, ignored, ".gitignore");
209 assertEntry(D, tracked, "a");
210 assertEntry(F, ignored, "a/x2");
211 assertEntry(F, ignored, "x1");
212 assertEntry(D, tracked, "x3");
213 assertEntry(F, ignored, "x3/y");
214 endWalk();
215 }
216
217 @Test
218 public void testRules() throws IOException {
219 writeIgnoreFile(".git/info/exclude", "*~", "/out");
220
221 writeIgnoreFile(".gitignore", "*.o", "/config");
222 writeTrashFile("config/secret", "");
223 writeTrashFile("mylib.c", "");
224 writeTrashFile("mylib.c~", "");
225 writeTrashFile("mylib.o", "");
226
227 writeTrashFile("out/object/foo.exe", "");
228 writeIgnoreFile("src/config/.gitignore", "lex.out");
229 writeTrashFile("src/config/lex.out", "");
230 writeTrashFile("src/config/config.c", "");
231 writeTrashFile("src/config/config.c~", "");
232 writeTrashFile("src/config/old/lex.out", "");
233
234 beginWalk();
235 assertEntry(F, tracked, ".gitignore");
236 assertEntry(D, ignored, "config");
237 assertEntry(F, ignored, "config/secret");
238 assertEntry(F, tracked, "mylib.c");
239 assertEntry(F, ignored, "mylib.c~");
240 assertEntry(F, ignored, "mylib.o");
241
242 assertEntry(D, ignored, "out");
243 assertEntry(D, ignored, "out/object");
244 assertEntry(F, ignored, "out/object/foo.exe");
245
246 assertEntry(D, tracked, "src");
247 assertEntry(D, tracked, "src/config");
248 assertEntry(F, tracked, "src/config/.gitignore");
249 assertEntry(F, tracked, "src/config/config.c");
250 assertEntry(F, ignored, "src/config/config.c~");
251 assertEntry(F, ignored, "src/config/lex.out");
252 assertEntry(D, tracked, "src/config/old");
253 assertEntry(F, ignored, "src/config/old/lex.out");
254 endWalk();
255 }
256
257 @Test
258 public void testNegation() throws IOException {
259
260 writeIgnoreFile(".gitignore", "*.o", "d");
261
262
263 writeIgnoreFile("src/a/b/.gitignore", "!keep.o");
264 writeTrashFile("src/a/b/keep.o", "");
265 writeTrashFile("src/a/b/nothere.o", "");
266
267
268 writeIgnoreFile("src/c/.gitignore", "!d");
269
270 writeIgnoreFile("src/c/d/.gitignore", "!keep.o");
271 writeTrashFile("src/c/d/keep.o", "");
272 writeTrashFile("src/c/d/nothere.o", "");
273
274 beginWalk();
275 assertEntry(F, tracked, ".gitignore");
276 assertEntry(D, tracked, "src");
277 assertEntry(D, tracked, "src/a");
278 assertEntry(D, tracked, "src/a/b");
279 assertEntry(F, tracked, "src/a/b/.gitignore");
280 assertEntry(F, tracked, "src/a/b/keep.o");
281 assertEntry(F, ignored, "src/a/b/nothere.o");
282
283 assertEntry(D, tracked, "src/c");
284 assertEntry(F, tracked, "src/c/.gitignore");
285 assertEntry(D, tracked, "src/c/d");
286 assertEntry(F, tracked, "src/c/d/.gitignore");
287 assertEntry(F, tracked, "src/c/d/keep.o");
288
289 assertEntry(F, ignored, "src/c/d/nothere.o");
290 endWalk();
291 }
292
293
294
295
296 @Test
297 public void testNegateAllExceptJavaInSrc() throws IOException {
298
299 writeIgnoreFile(".gitignore", "/*", "!/src/");
300 writeTrashFile("nothere.o", "");
301
302
303 writeIgnoreFile("src/.gitignore", "*", "!*.java");
304
305 writeTrashFile("src/keep.java", "");
306 writeTrashFile("src/nothere.o", "");
307 writeTrashFile("src/a/nothere.o", "");
308
309 beginWalk();
310 assertEntry(F, ignored, ".gitignore");
311 assertEntry(F, ignored, "nothere.o");
312 assertEntry(D, tracked, "src");
313 assertEntry(F, ignored, "src/.gitignore");
314 assertEntry(D, ignored, "src/a");
315 assertEntry(F, ignored, "src/a/nothere.o");
316 assertEntry(F, tracked, "src/keep.java");
317 assertEntry(F, ignored, "src/nothere.o");
318 endWalk();
319 }
320
321
322
323
324 @Test
325 public void testNegationAllExceptJavaInSrcAndExceptChildDirInSrc()
326 throws IOException {
327
328 writeIgnoreFile(".gitignore", "/*", "!/src/");
329 writeTrashFile("nothere.o", "");
330
331
332
333 writeIgnoreFile("src/.gitignore", "*", "!*.java", "!*/");
334
335 writeTrashFile("src/keep.java", "");
336 writeTrashFile("src/nothere.o", "");
337 writeTrashFile("src/a/keep.java", "");
338 writeTrashFile("src/a/keep.o", "");
339
340 beginWalk();
341 assertEntry(F, ignored, ".gitignore");
342 assertEntry(F, ignored, "nothere.o");
343 assertEntry(D, tracked, "src");
344 assertEntry(F, ignored, "src/.gitignore");
345 assertEntry(D, tracked, "src/a");
346 assertEntry(F, tracked, "src/a/keep.java");
347 assertEntry(F, ignored, "src/a/keep.o");
348 assertEntry(F, tracked, "src/keep.java");
349 assertEntry(F, ignored, "src/nothere.o");
350 endWalk();
351 }
352
353
354
355
356 @Test
357 public void testRepeatedNegation() throws IOException {
358 writeIgnoreFile(".gitignore", "e", "!e", "e", "!e", "e");
359
360 writeTrashFile("e/nothere.o", "");
361
362 beginWalk();
363 assertEntry(F, tracked, ".gitignore");
364 assertEntry(D, ignored, "e");
365 assertEntry(F, ignored, "e/nothere.o");
366 endWalk();
367 }
368
369
370
371
372 @Test
373 public void testRepeatedNegationInDifferentFiles1() throws IOException {
374 writeIgnoreFile(".gitignore", "*.o", "e");
375
376 writeIgnoreFile("e/.gitignore", "!e");
377 writeTrashFile("e/nothere.o", "");
378
379 beginWalk();
380 assertEntry(F, tracked, ".gitignore");
381 assertEntry(D, ignored, "e");
382 assertEntry(F, ignored, "e/.gitignore");
383 assertEntry(F, ignored, "e/nothere.o");
384 endWalk();
385 }
386
387
388
389
390 @Test
391 public void testRepeatedNegationInDifferentFiles2() throws IOException {
392 writeIgnoreFile(".gitignore", "*.o", "e");
393
394 writeIgnoreFile("a/.gitignore", "!e");
395 writeTrashFile("a/e/nothere.o", "");
396
397 beginWalk();
398 assertEntry(F, tracked, ".gitignore");
399 assertEntry(D, tracked, "a");
400 assertEntry(F, tracked, "a/.gitignore");
401 assertEntry(D, tracked, "a/e");
402 assertEntry(F, ignored, "a/e/nothere.o");
403 endWalk();
404 }
405
406
407
408
409 @Test
410 public void testRepeatedNegationInDifferentFiles3() throws IOException {
411 writeIgnoreFile(".gitignore", "*.o");
412
413 writeIgnoreFile("a/.gitignore", "e");
414 writeIgnoreFile("a/b/.gitignore", "!e");
415 writeTrashFile("a/b/e/nothere.o", "");
416
417 beginWalk();
418 assertEntry(F, tracked, ".gitignore");
419 assertEntry(D, tracked, "a");
420 assertEntry(F, tracked, "a/.gitignore");
421 assertEntry(D, tracked, "a/b");
422 assertEntry(F, tracked, "a/b/.gitignore");
423 assertEntry(D, tracked, "a/b/e");
424 assertEntry(F, ignored, "a/b/e/nothere.o");
425 endWalk();
426 }
427
428 @Test
429 public void testRepeatedNegationInDifferentFiles4() throws IOException {
430 writeIgnoreFile(".gitignore", "*.o");
431
432 writeIgnoreFile("a/.gitignore", "e");
433
434
435 writeIgnoreFile("a/b/.gitignore", "#");
436 writeIgnoreFile("a/b/c/.gitignore", "!e");
437 writeTrashFile("a/b/c/e/nothere.o", "");
438
439 beginWalk();
440 assertEntry(F, tracked, ".gitignore");
441 assertEntry(D, tracked, "a");
442 assertEntry(F, tracked, "a/.gitignore");
443 assertEntry(D, tracked, "a/b");
444 assertEntry(F, tracked, "a/b/.gitignore");
445 assertEntry(D, tracked, "a/b/c");
446 assertEntry(F, tracked, "a/b/c/.gitignore");
447 assertEntry(D, tracked, "a/b/c/e");
448 assertEntry(F, ignored, "a/b/c/e/nothere.o");
449 endWalk();
450 }
451
452 @Test
453 public void testRepeatedNegationInDifferentFiles5() throws IOException {
454 writeIgnoreFile(".gitignore", "e");
455 writeIgnoreFile("a/.gitignore", "e");
456 writeIgnoreFile("a/b/.gitignore", "!e");
457 writeTrashFile("a/b/e/nothere.o", "");
458
459 beginWalk();
460 assertEntry(F, tracked, ".gitignore");
461 assertEntry(D, tracked, "a");
462 assertEntry(F, tracked, "a/.gitignore");
463 assertEntry(D, tracked, "a/b");
464 assertEntry(F, tracked, "a/b/.gitignore");
465 assertEntry(D, tracked, "a/b/e");
466 assertEntry(F, tracked, "a/b/e/nothere.o");
467 endWalk();
468 }
469
470 @Test
471 public void testIneffectiveNegationDifferentLevels1() throws IOException {
472 writeIgnoreFile(".gitignore", "a/b/e/", "!a/b/e/*");
473 writeTrashFile("a/b/e/nothere.o", "");
474
475 beginWalk();
476 assertEntry(F, tracked, ".gitignore");
477 assertEntry(D, tracked, "a");
478 assertEntry(D, tracked, "a/b");
479 assertEntry(D, ignored, "a/b/e");
480 assertEntry(F, ignored, "a/b/e/nothere.o");
481 endWalk();
482 }
483
484 @Test
485 public void testIneffectiveNegationDifferentLevels2() throws IOException {
486 writeIgnoreFile(".gitignore", "a/b/e/");
487 writeIgnoreFile("a/.gitignore", "!b/e/*");
488 writeTrashFile("a/b/e/nothere.o", "");
489
490 beginWalk();
491 assertEntry(F, tracked, ".gitignore");
492 assertEntry(D, tracked, "a");
493 assertEntry(F, tracked, "a/.gitignore");
494 assertEntry(D, tracked, "a/b");
495 assertEntry(D, ignored, "a/b/e");
496 assertEntry(F, ignored, "a/b/e/nothere.o");
497 endWalk();
498 }
499
500 @Test
501 public void testIneffectiveNegationDifferentLevels3() throws IOException {
502 writeIgnoreFile(".gitignore", "a/b/e/");
503 writeIgnoreFile("a/b/.gitignore", "!e/*");
504 writeTrashFile("a/b/e/nothere.o", "");
505
506 beginWalk();
507 assertEntry(F, tracked, ".gitignore");
508 assertEntry(D, tracked, "a");
509 assertEntry(D, tracked, "a/b");
510 assertEntry(F, tracked, "a/b/.gitignore");
511 assertEntry(D, ignored, "a/b/e");
512 assertEntry(F, ignored, "a/b/e/nothere.o");
513 endWalk();
514 }
515
516 @Test
517 public void testIneffectiveNegationDifferentLevels4() throws IOException {
518 writeIgnoreFile(".gitignore", "a/b/e/");
519 writeIgnoreFile("a/b/e/.gitignore", "!*");
520 writeTrashFile("a/b/e/nothere.o", "");
521
522 beginWalk();
523 assertEntry(F, tracked, ".gitignore");
524 assertEntry(D, tracked, "a");
525 assertEntry(D, tracked, "a/b");
526 assertEntry(D, ignored, "a/b/e");
527 assertEntry(F, ignored, "a/b/e/.gitignore");
528 assertEntry(F, ignored, "a/b/e/nothere.o");
529 endWalk();
530 }
531
532 @Test
533 public void testIneffectiveNegationDifferentLevels5() throws IOException {
534 writeIgnoreFile("a/.gitignore", "b/e/");
535 writeIgnoreFile("a/b/.gitignore", "!e/*");
536 writeTrashFile("a/b/e/nothere.o", "");
537
538 beginWalk();
539 assertEntry(D, tracked, "a");
540 assertEntry(F, tracked, "a/.gitignore");
541 assertEntry(D, tracked, "a/b");
542 assertEntry(F, tracked, "a/b/.gitignore");
543 assertEntry(D, ignored, "a/b/e");
544 assertEntry(F, ignored, "a/b/e/nothere.o");
545 endWalk();
546 }
547
548 @Test
549 public void testEmptyIgnoreRules() throws IOException {
550 IgnoreNode node = new IgnoreNode();
551 node.parse(writeToString("", "#", "!", "[[=a=]]"));
552 assertEquals(new ArrayList<>(), node.getRules());
553 node.parse(writeToString(" ", " / "));
554 assertEquals(2, node.getRules().size());
555 }
556
557 @Test
558 public void testSlashOnlyMatchesDirectory() throws IOException {
559 writeIgnoreFile(".gitignore", "out/");
560 writeTrashFile("out", "");
561
562 beginWalk();
563 assertEntry(F, tracked, ".gitignore");
564 assertEntry(F, tracked, "out");
565
566 FileUtils.delete(new File(trash, "out"));
567 writeTrashFile("out/foo", "");
568
569 beginWalk();
570 assertEntry(F, tracked, ".gitignore");
571 assertEntry(D, ignored, "out");
572 assertEntry(F, ignored, "out/foo");
573 endWalk();
574 }
575
576 @Test
577 public void testSlashMatchesDirectory() throws IOException {
578 writeIgnoreFile(".gitignore", "out2/");
579
580 writeTrashFile("out1/out1", "");
581 writeTrashFile("out1/out2", "");
582 writeTrashFile("out2/out1", "");
583 writeTrashFile("out2/out2", "");
584
585 beginWalk();
586 assertEntry(F, tracked, ".gitignore");
587 assertEntry(D, tracked, "out1");
588 assertEntry(F, tracked, "out1/out1");
589 assertEntry(F, tracked, "out1/out2");
590 assertEntry(D, ignored, "out2");
591 assertEntry(F, ignored, "out2/out1");
592 assertEntry(F, ignored, "out2/out2");
593 endWalk();
594 }
595
596 @Test
597 public void testWildcardWithSlashMatchesDirectory() throws IOException {
598 writeIgnoreFile(".gitignore", "out2*/");
599
600 writeTrashFile("out1/out1.txt", "");
601 writeTrashFile("out1/out2", "");
602 writeTrashFile("out1/out2.txt", "");
603 writeTrashFile("out1/out2x/a", "");
604 writeTrashFile("out2/out1.txt", "");
605 writeTrashFile("out2/out2.txt", "");
606 writeTrashFile("out2x/out1.txt", "");
607 writeTrashFile("out2x/out2.txt", "");
608
609 beginWalk();
610 assertEntry(F, tracked, ".gitignore");
611 assertEntry(D, tracked, "out1");
612 assertEntry(F, tracked, "out1/out1.txt");
613 assertEntry(F, tracked, "out1/out2");
614 assertEntry(F, tracked, "out1/out2.txt");
615 assertEntry(D, ignored, "out1/out2x");
616 assertEntry(F, ignored, "out1/out2x/a");
617 assertEntry(D, ignored, "out2");
618 assertEntry(F, ignored, "out2/out1.txt");
619 assertEntry(F, ignored, "out2/out2.txt");
620 assertEntry(D, ignored, "out2x");
621 assertEntry(F, ignored, "out2x/out1.txt");
622 assertEntry(F, ignored, "out2x/out2.txt");
623 endWalk();
624 }
625
626 @Test
627 public void testWithSlashDoesNotMatchInSubDirectory() throws IOException {
628 writeIgnoreFile(".gitignore", "a/b");
629 writeTrashFile("a/a", "");
630 writeTrashFile("a/b", "");
631 writeTrashFile("src/a/a", "");
632 writeTrashFile("src/a/b", "");
633
634 beginWalk();
635 assertEntry(F, tracked, ".gitignore");
636 assertEntry(D, tracked, "a");
637 assertEntry(F, tracked, "a/a");
638 assertEntry(F, ignored, "a/b");
639 assertEntry(D, tracked, "src");
640 assertEntry(D, tracked, "src/a");
641 assertEntry(F, tracked, "src/a/a");
642 assertEntry(F, tracked, "src/a/b");
643 endWalk();
644 }
645
646 @Test
647 public void testNoPatterns() throws IOException {
648 writeIgnoreFile(".gitignore", "", " ", "# comment", "/");
649 writeTrashFile("a/a", "");
650
651 beginWalk();
652 assertEntry(F, tracked, ".gitignore");
653 assertEntry(D, tracked, "a");
654 assertEntry(F, tracked, "a/a");
655 endWalk();
656 }
657
658 @Test
659 public void testLeadingSpaces() throws IOException {
660 writeTrashFile(" a/ a", "");
661 writeTrashFile(" a/ a", "");
662 writeTrashFile(" a/a", "");
663 writeTrashFile(" a/ a", "");
664 writeTrashFile(" a/ a", "");
665 writeTrashFile(" a/a", "");
666 writeIgnoreFile(".gitignore", " a", " a");
667 writeTrashFile("a/ a", "");
668 writeTrashFile("a/ a", "");
669 writeTrashFile("a/a", "");
670
671 beginWalk();
672 assertEntry(D, ignored, " a");
673 assertEntry(F, ignored, " a/ a");
674 assertEntry(F, ignored, " a/ a");
675 assertEntry(F, ignored, " a/a");
676 assertEntry(D, ignored, " a");
677 assertEntry(F, ignored, " a/ a");
678 assertEntry(F, ignored, " a/ a");
679 assertEntry(F, ignored, " a/a");
680 assertEntry(F, tracked, ".gitignore");
681 assertEntry(D, tracked, "a");
682 assertEntry(F, ignored, "a/ a");
683 assertEntry(F, ignored, "a/ a");
684 assertEntry(F, tracked, "a/a");
685 endWalk();
686 }
687
688 @Test
689 public void testTrailingSpaces() throws IOException {
690
691
692 org.junit.Assume.assumeFalse(SystemReader.getInstance().isWindows());
693 writeTrashFile("a /a", "");
694 writeTrashFile("a /a ", "");
695 writeTrashFile("a /a ", "");
696 writeTrashFile("a /a", "");
697 writeTrashFile("a /a ", "");
698 writeTrashFile("a /a ", "");
699 writeTrashFile("a/a", "");
700 writeTrashFile("a/a ", "");
701 writeTrashFile("a/a ", "");
702 writeTrashFile("b/c", "");
703
704 writeIgnoreFile(".gitignore", "a\\ ", "a \\ ", "b/ ");
705
706 beginWalk();
707 assertEntry(F, tracked, ".gitignore");
708 assertEntry(D, ignored, "a ");
709 assertEntry(F, ignored, "a /a");
710 assertEntry(F, ignored, "a /a ");
711 assertEntry(F, ignored, "a /a ");
712 assertEntry(D, ignored, "a ");
713 assertEntry(F, ignored, "a /a");
714 assertEntry(F, ignored, "a /a ");
715 assertEntry(F, ignored, "a /a ");
716 assertEntry(D, tracked, "a");
717 assertEntry(F, tracked, "a/a");
718 assertEntry(F, ignored, "a/a ");
719 assertEntry(F, ignored, "a/a ");
720 assertEntry(D, ignored, "b");
721 assertEntry(F, ignored, "b/c");
722 endWalk();
723 }
724
725 @Test
726 public void testToString() throws Exception {
727 assertEquals(Arrays.asList("").toString(), new IgnoreNode().toString());
728 assertEquals(Arrays.asList("hello").toString(),
729 new IgnoreNode(Arrays.asList(new FastIgnoreRule("hello")))
730 .toString());
731 }
732
733 private void beginWalk() {
734 walk = new TreeWalk(db);
735 FileTreeIterator iter = new FileTreeIterator(db);
736 iter.setWalkIgnoredDirectories(true);
737 walk.addTree(iter);
738 }
739
740 private void endWalk() throws IOException {
741 assertFalse("Not all files tested", walk.next());
742 }
743
744 private void assertEntry(FileMode type, boolean entryIgnored,
745 String pathName) throws IOException {
746 assertTrue("walk has entry", walk.next());
747 assertEquals(pathName, walk.getPathString());
748 assertEquals(type, walk.getFileMode(0));
749
750 WorkingTreeIterator itr = walk.getTree(0, WorkingTreeIterator.class);
751 assertNotNull("has tree", itr);
752 assertEquals("is ignored", entryIgnored, itr.isEntryIgnored());
753 if (D.equals(type))
754 walk.enterSubtree();
755 }
756
757 private void writeIgnoreFile(String name, String... rules)
758 throws IOException {
759 StringBuilder data = new StringBuilder();
760 for (String line : rules)
761 data.append(line + "\n");
762 writeTrashFile(name, data.toString());
763 }
764
765 private InputStream writeToString(String... rules) {
766 StringBuilder data = new StringBuilder();
767 for (String line : rules) {
768 data.append(line + "\n");
769 }
770 return new ByteArrayInputStream(data.toString().getBytes(UTF_8));
771 }
772 }