1
2
3
4
5
6
7
8
9
10
11 package org.eclipse.jgit.treewalk.filter;
12
13 import static org.junit.Assert.assertEquals;
14 import static org.junit.Assert.assertFalse;
15 import static org.junit.Assert.assertTrue;
16 import static org.junit.Assert.fail;
17
18 import java.io.File;
19
20 import org.eclipse.jgit.api.Git;
21 import org.eclipse.jgit.dircache.DirCacheIterator;
22 import org.eclipse.jgit.junit.RepositoryTestCase;
23 import org.eclipse.jgit.revwalk.RevCommit;
24 import org.eclipse.jgit.treewalk.FileTreeIterator;
25 import org.eclipse.jgit.treewalk.TreeWalk;
26 import org.eclipse.jgit.util.FileUtils;
27 import org.junit.Before;
28 import org.junit.Test;
29
30 public class IndexDiffFilterTest extends RepositoryTestCase {
31 private static final String FILE = "file";
32
33 private static final String UNTRACKED_FILE = "untracked_file";
34
35 private static final String IGNORED_FILE = "ignored_file";
36
37 private static final String FILE_IN_FOLDER = "folder/file";
38
39 private static final String UNTRACKED_FILE_IN_FOLDER = "folder/untracked_file";
40
41 private static final String IGNORED_FILE_IN_FOLDER = "folder/ignored_file";
42
43 private static final String FILE_IN_IGNORED_FOLDER = "ignored_folder/file";
44
45 private static final String FOLDER = "folder";
46
47 private static final String UNTRACKED_FOLDER = "untracked_folder";
48
49 private static final String IGNORED_FOLDER = "ignored_folder";
50
51 private static final String GITIGNORE = ".gitignore";
52
53 private static final String FILE_CONTENT = "content";
54
55 private static final String MODIFIED_FILE_CONTENT = "modified_content";
56
57 private Git git;
58
59 @Override
60 @Before
61 public void setUp() throws Exception {
62 super.setUp();
63 git = new Git(db);
64 }
65
66 @Test
67 public void testRecursiveTreeWalk() throws Exception {
68 RevCommit commit = writeFileInFolderAndCommit();
69 deleteAll();
70 writeFileWithFolderName();
71
72 try (TreeWalk treeWalk = createTreeWalk(commit)) {
73 assertTrue(treeWalk.next());
74 assertEquals("folder", treeWalk.getPathString());
75 assertTrue(treeWalk.next());
76 assertEquals("folder/file", treeWalk.getPathString());
77 assertFalse(treeWalk.next());
78 }
79 }
80
81 @Test
82 public void testNonRecursiveTreeWalk() throws Exception {
83 RevCommit commit = writeFileInFolderAndCommit();
84 deleteAll();
85 writeFileWithFolderName();
86
87 try (TreeWalk treeWalk = createNonRecursiveTreeWalk(commit)) {
88 assertTrue(treeWalk.next());
89 assertEquals("folder", treeWalk.getPathString());
90 assertTrue(treeWalk.next());
91 assertEquals("folder", treeWalk.getPathString());
92 assertTrue(treeWalk.isSubtree());
93 treeWalk.enterSubtree();
94 assertTrue(treeWalk.next());
95 assertEquals("folder/file", treeWalk.getPathString());
96 assertFalse(treeWalk.next());
97 }
98 }
99
100 @Test
101 public void testFileCommitted() throws Exception {
102 RevCommit commit = writeFileAndCommit();
103 try (TreeWalk treeWalk = createTreeWalk(commit)) {
104 assertFalse(treeWalk.next());
105 }
106 }
107
108 @Test
109 public void testConflicts() throws Exception {
110 RevCommit initial = git.commit().setMessage("initial").call();
111 writeTrashFile(FILE, "master");
112 git.add().addFilepattern(FILE).call();
113 RevCommit master = git.commit().setMessage("master").call();
114 git.checkout().setName("refs/heads/side")
115 .setCreateBranch(true).setStartPoint(initial).call();
116 writeTrashFile(FILE, "side");
117 git.add().addFilepattern(FILE).call();
118 RevCommit side = git.commit().setMessage("side").call();
119 assertFalse(git.merge().include("master", master).call()
120 .getMergeStatus()
121 .isSuccessful());
122 assertEquals(read(FILE),
123 "<<<<<<< HEAD\nside\n=======\nmaster\n>>>>>>> master\n");
124 writeTrashFile(FILE, "master");
125
126 try (TreeWalk treeWalk = createTreeWalk(side)) {
127 int count = 0;
128 while (treeWalk.next())
129 count++;
130 assertEquals(2, count);
131 }
132 }
133
134 @Test
135 public void testFileInFolderCommitted() throws Exception {
136 RevCommit commit = writeFileInFolderAndCommit();
137 try (TreeWalk treeWalk = createTreeWalk(commit)) {
138 assertFalse(treeWalk.next());
139 }
140 }
141
142 @Test
143 public void testEmptyFolderCommitted() throws Exception {
144 RevCommit commit = createEmptyFolderAndCommit();
145 try (TreeWalk treeWalk = createTreeWalk(commit)) {
146 assertFalse(treeWalk.next());
147 }
148 }
149
150 @Test
151 public void testFileCommittedChangedNotModified() throws Exception {
152 RevCommit commit = writeFileAndCommit();
153 writeFile();
154 try (TreeWalk treeWalk = createTreeWalk(commit)) {
155 assertFalse(treeWalk.next());
156 }
157 }
158
159 @Test
160 public void testFileInFolderCommittedChangedNotModified() throws Exception {
161 RevCommit commit = writeFileInFolderAndCommit();
162 writeFileInFolder();
163 try (TreeWalk treeWalk = createTreeWalk(commit)) {
164 assertFalse(treeWalk.next());
165 }
166 }
167
168 @Test
169 public void testFileCommittedModified() throws Exception {
170 RevCommit commit = writeFileAndCommit();
171 writeFileModified();
172 try (TreeWalk treeWalk = createTreeWalk(commit)) {
173 assertPaths(treeWalk, FILE);
174 }
175 }
176
177 @Test
178 public void testFileInFolderCommittedModified() throws Exception {
179 RevCommit commit = writeFileInFolderAndCommit();
180 writeFileInFolderModified();
181 try (TreeWalk treeWalk = createTreeWalk(commit)) {
182 assertPaths(treeWalk, FILE_IN_FOLDER);
183 }
184 }
185
186 @Test
187 public void testFileCommittedDeleted() throws Exception {
188 RevCommit commit = writeFileAndCommit();
189 deleteFile();
190 try (TreeWalk treeWalk = createTreeWalk(commit)) {
191 assertPaths(treeWalk, FILE);
192 }
193 }
194
195 @Test
196 public void testFileInFolderCommittedDeleted() throws Exception {
197 RevCommit commit = writeFileInFolderAndCommit();
198 deleteFileInFolder();
199 try (TreeWalk treeWalk = createTreeWalk(commit)) {
200 assertPaths(treeWalk, FILE_IN_FOLDER);
201 }
202 }
203
204 @Test
205 public void testFileInFolderCommittedAllDeleted() throws Exception {
206 RevCommit commit = writeFileInFolderAndCommit();
207 deleteAll();
208 try (TreeWalk treeWalk = createTreeWalk(commit)) {
209 assertPaths(treeWalk, FILE_IN_FOLDER);
210 }
211 }
212
213 @Test
214 public void testEmptyFolderCommittedDeleted() throws Exception {
215 RevCommit commit = createEmptyFolderAndCommit();
216 deleteFolder();
217 try (TreeWalk treeWalk = createTreeWalk(commit)) {
218 assertFalse(treeWalk.next());
219 }
220 }
221
222 @Test
223 public void testFileCommittedModifiedCommittedComparedWithInitialCommit()
224 throws Exception {
225 RevCommit commit = writeFileAndCommit();
226 writeFileModifiedAndCommit();
227 try (TreeWalk treeWalk = createTreeWalk(commit)) {
228 assertPaths(treeWalk, FILE);
229 }
230 }
231
232 @Test
233 public void testFileInFolderCommittedModifiedCommittedComparedWithInitialCommit()
234 throws Exception {
235 RevCommit commit = writeFileInFolderAndCommit();
236 writeFileInFolderModifiedAndCommit();
237 try (TreeWalk treeWalk = createTreeWalk(commit)) {
238 assertPaths(treeWalk, FILE_IN_FOLDER);
239 }
240 }
241
242 @Test
243 public void testFileCommittedDeletedCommittedComparedWithInitialCommit()
244 throws Exception {
245 RevCommit commit = writeFileAndCommit();
246 deleteFileAndCommit();
247 try (TreeWalk treeWalk = createTreeWalk(commit)) {
248 assertPaths(treeWalk, FILE);
249 }
250 }
251
252 @Test
253 public void testFileInFolderCommittedDeletedCommittedComparedWithInitialCommit()
254 throws Exception {
255 RevCommit commit = writeFileInFolderAndCommit();
256 deleteFileInFolderAndCommit();
257 try (TreeWalk treeWalk = createTreeWalk(commit)) {
258 assertPaths(treeWalk, FILE_IN_FOLDER);
259 }
260 }
261
262 @Test
263 public void testFileInFolderCommittedAllDeletedCommittedComparedWithInitialCommit()
264 throws Exception {
265 RevCommit commit = writeFileInFolderAndCommit();
266 deleteAllAndCommit();
267 try (TreeWalk treeWalk = createTreeWalk(commit)) {
268 assertPaths(treeWalk, FILE_IN_FOLDER);
269 }
270 }
271
272 @Test
273 public void testEmptyFolderCommittedDeletedCommittedComparedWithInitialCommit()
274 throws Exception {
275 RevCommit commit = createEmptyFolderAndCommit();
276 deleteFolderAndCommit();
277 try (TreeWalk treeWalk = createTreeWalk(commit)) {
278 assertFalse(treeWalk.next());
279 }
280 }
281
282 @Test
283 public void testFileUntracked() throws Exception {
284 RevCommit commit = writeFileAndCommit();
285 writeFileUntracked();
286 try (TreeWalk treeWalk = createTreeWalk(commit)) {
287 assertPaths(treeWalk, UNTRACKED_FILE);
288 }
289 }
290
291 @Test
292 public void testFileInFolderUntracked() throws Exception {
293 RevCommit commit = writeFileInFolderAndCommit();
294 writeFileInFolderUntracked();
295 try (TreeWalk treeWalk = createTreeWalk(commit)) {
296 assertPaths(treeWalk, UNTRACKED_FILE_IN_FOLDER);
297 }
298 }
299
300 @Test
301 public void testEmptyFolderUntracked() throws Exception {
302 RevCommit commit = createEmptyFolderAndCommit();
303 createEmptyFolderUntracked();
304 try (TreeWalk treeWalk = createTreeWalk(commit)) {
305 assertFalse(treeWalk.next());
306 }
307 }
308
309 @Test
310 public void testFileIgnored() throws Exception {
311 RevCommit commit = writeFileAndCommit();
312 writeFileIgnored();
313 try (TreeWalk treeWalk = createTreeWalk(commit)) {
314 assertFalse(treeWalk.next());
315 }
316 }
317
318 @Test
319 public void testFileInFolderIgnored() throws Exception {
320 RevCommit commit = writeFileInFolderAndCommit();
321 writeFileInFolderIgnored();
322 try (TreeWalk treeWalk = createTreeWalk(commit)) {
323 assertFalse(treeWalk.next());
324 }
325 }
326
327 @Test
328 public void testFileInFolderAllIgnored() throws Exception {
329 RevCommit commit = writeFileInFolderAndCommit();
330 writeFileInFolderAllIgnored();
331 try (TreeWalk treeWalk = createTreeWalk(commit)) {
332 assertFalse(treeWalk.next());
333 }
334 }
335
336 @Test
337 public void testEmptyFolderIgnored() throws Exception {
338 RevCommit commit = createEmptyFolderAndCommit();
339 createEmptyFolderIgnored();
340 try (TreeWalk treeWalk = createTreeWalk(commit)) {
341 assertFalse(treeWalk.next());
342 }
343 }
344
345 @Test
346 public void testFileIgnoredNotHonored() throws Exception {
347 RevCommit commit = writeFileAndCommit();
348 writeFileIgnored();
349 try (TreeWalk treeWalk = createTreeWalkDishonorIgnores(commit)) {
350 assertPaths(treeWalk, IGNORED_FILE, GITIGNORE);
351 }
352 }
353
354 @Test
355 public void testFileCommittedModifiedIgnored() throws Exception {
356 RevCommit commit = writeFileAndCommit();
357 writeFileModifiedIgnored();
358 try (TreeWalk treeWalk = createTreeWalk(commit)) {
359 assertPaths(treeWalk, FILE);
360 }
361 }
362
363 @Test
364 public void testFileInFolderCommittedModifiedIgnored() throws Exception {
365 RevCommit commit = writeFileInFolderAndCommit();
366 writeFileInFolderModifiedIgnored();
367 try (TreeWalk treeWalk = createTreeWalk(commit)) {
368 assertPaths(treeWalk, FILE_IN_FOLDER);
369 }
370 }
371
372 @Test
373 public void testFileInFolderCommittedModifiedAllIgnored() throws Exception {
374 RevCommit commit = writeFileInFolderAndCommit();
375 writeFileInFolderModifiedAllIgnored();
376 try (TreeWalk treeWalk = createTreeWalk(commit)) {
377 assertPaths(treeWalk, FILE_IN_FOLDER);
378 }
379 }
380
381 @Test
382 public void testFileCommittedDeletedCommittedIgnoredComparedWithInitialCommit()
383 throws Exception {
384 RevCommit commit = writeFileAndCommit();
385 deleteFileAndCommit();
386 rewriteFileIgnored();
387 try (TreeWalk treeWalk = createTreeWalk(commit)) {
388 assertPaths(treeWalk, FILE);
389 }
390 }
391
392 @Test
393 public void testFileInFolderCommittedDeletedCommittedIgnoredComparedWithInitialCommit()
394 throws Exception {
395 RevCommit commit = writeFileInFolderAndCommit();
396 deleteFileInFolderAndCommit();
397 rewriteFileInFolderIgnored();
398 try (TreeWalk treeWalk = createTreeWalk(commit)) {
399 assertPaths(treeWalk, FILE_IN_FOLDER);
400 }
401 }
402
403 @Test
404 public void testFileInFolderCommittedAllDeletedCommittedAllIgnoredComparedWithInitialCommit()
405 throws Exception {
406 RevCommit commit = writeFileInFolderAndCommit();
407 deleteAllAndCommit();
408 rewriteFileInFolderAllIgnored();
409 try (TreeWalk treeWalk = createTreeWalk(commit)) {
410 assertPaths(treeWalk, FILE_IN_FOLDER);
411 }
412 }
413
414 @Test
415 public void testEmptyFolderCommittedDeletedCommittedIgnoredComparedWithInitialCommit()
416 throws Exception {
417 RevCommit commit = createEmptyFolderAndCommit();
418 deleteFolderAndCommit();
419 recreateEmptyFolderIgnored();
420 try (TreeWalk treeWalk = createTreeWalk(commit)) {
421 assertFalse(treeWalk.next());
422 }
423 }
424
425 @Test
426 public void testFileInFolderCommittedNonRecursive() throws Exception {
427 RevCommit commit = writeFileInFolderAndCommit();
428 try (TreeWalk treeWalk = createNonRecursiveTreeWalk(commit)) {
429 assertPaths(treeWalk, FOLDER);
430 }
431 }
432
433 @Test
434 public void testFolderChangedToFile() throws Exception {
435 RevCommit commit = writeFileInFolderAndCommit();
436 deleteAll();
437 writeFileWithFolderName();
438 try (TreeWalk treeWalk = createTreeWalk(commit)) {
439 assertPaths(treeWalk, FOLDER, FILE_IN_FOLDER);
440 }
441 }
442
443 @Test
444 public void testFolderChangedToFileCommittedComparedWithInitialCommit()
445 throws Exception {
446 RevCommit commit = writeFileInFolderAndCommit();
447 deleteAll();
448 writeFileWithFolderNameAndCommit();
449 try (TreeWalk treeWalk = createTreeWalk(commit)) {
450 assertPaths(treeWalk, FOLDER, FILE_IN_FOLDER);
451 }
452 }
453
454 private void writeFile() throws Exception {
455 writeTrashFile(FILE, FILE_CONTENT);
456 }
457
458 private RevCommit writeFileAndCommit() throws Exception {
459 writeFile();
460 return commitAdd();
461 }
462
463 private void writeFileModified() throws Exception {
464 writeTrashFile(FILE, MODIFIED_FILE_CONTENT);
465 }
466
467 private void writeFileModifiedAndCommit() throws Exception {
468 writeFileModified();
469 commitAdd();
470 }
471
472 private void writeFileUntracked() throws Exception {
473 writeTrashFile(UNTRACKED_FILE, FILE_CONTENT);
474 }
475
476 private void writeFileIgnored() throws Exception {
477 writeTrashFile(IGNORED_FILE, FILE_CONTENT);
478 writeTrashFile(GITIGNORE, GITIGNORE + "\n" + IGNORED_FILE);
479 }
480
481 private void writeFileModifiedIgnored() throws Exception {
482 writeFileModified();
483 writeTrashFile(GITIGNORE, GITIGNORE + "\n" + FILE);
484 }
485
486 private void rewriteFileIgnored() throws Exception {
487 writeFile();
488 writeTrashFile(GITIGNORE, GITIGNORE + "\n" + FILE);
489 }
490
491 private void writeFileWithFolderName() throws Exception {
492 writeTrashFile(FOLDER, FILE_CONTENT);
493 }
494
495 private void writeFileWithFolderNameAndCommit() throws Exception {
496 writeFileWithFolderName();
497 commitAdd();
498 }
499
500 private void deleteFile() throws Exception {
501 deleteTrashFile(FILE);
502 }
503
504 private void deleteFileAndCommit() throws Exception {
505 deleteFile();
506 commitRm(FILE);
507 }
508
509 private void writeFileInFolder() throws Exception {
510 writeTrashFile(FILE_IN_FOLDER, FILE_CONTENT);
511 }
512
513 private RevCommit writeFileInFolderAndCommit() throws Exception {
514 writeFileInFolder();
515 return commitAdd();
516 }
517
518 private void writeFileInFolderModified() throws Exception {
519 writeTrashFile(FILE_IN_FOLDER, MODIFIED_FILE_CONTENT);
520 }
521
522 private void writeFileInFolderModifiedAndCommit() throws Exception {
523 writeFileInFolderModified();
524 commitAdd();
525 }
526
527 private void writeFileInFolderUntracked() throws Exception {
528 writeTrashFile(UNTRACKED_FILE_IN_FOLDER, FILE_CONTENT);
529 }
530
531 private void writeFileInFolderIgnored() throws Exception {
532 writeTrashFile(IGNORED_FILE_IN_FOLDER, FILE_CONTENT);
533 writeTrashFile(GITIGNORE, GITIGNORE + "\n" + IGNORED_FILE_IN_FOLDER);
534 }
535
536 private void writeFileInFolderAllIgnored() throws Exception {
537 writeTrashFile(FILE_IN_IGNORED_FOLDER, FILE_CONTENT);
538 writeTrashFile(GITIGNORE, GITIGNORE + "\n" + IGNORED_FOLDER + "/");
539 }
540
541 private void writeFileInFolderModifiedIgnored() throws Exception {
542 writeFileInFolderModified();
543 writeTrashFile(GITIGNORE, GITIGNORE + "\n" + FILE_IN_FOLDER);
544 }
545
546 private void rewriteFileInFolderIgnored() throws Exception {
547 writeFileInFolder();
548 writeTrashFile(GITIGNORE, GITIGNORE + "\n" + FILE_IN_FOLDER);
549 }
550
551 private void writeFileInFolderModifiedAllIgnored() throws Exception {
552 writeFileInFolderModified();
553 writeTrashFile(GITIGNORE, GITIGNORE + "\n" + FOLDER + "/");
554 }
555
556 private void rewriteFileInFolderAllIgnored() throws Exception {
557 writeFileInFolder();
558 writeTrashFile(GITIGNORE, GITIGNORE + "\n" + FOLDER + "/");
559 }
560
561 private void deleteFileInFolder() throws Exception {
562 deleteTrashFile(FILE_IN_FOLDER);
563 }
564
565 private void deleteFileInFolderAndCommit() throws Exception {
566 deleteFileInFolder();
567 commitRm(FILE_IN_FOLDER);
568 }
569
570 private void createEmptyFolder() throws Exception {
571 File path = new File(db.getWorkTree(), FOLDER);
572 FileUtils.mkdir(path);
573 }
574
575 private RevCommit createEmptyFolderAndCommit() throws Exception {
576 createEmptyFolder();
577 return commitAdd();
578 }
579
580 private void createEmptyFolderUntracked() throws Exception {
581 File path = new File(db.getWorkTree(), UNTRACKED_FOLDER);
582 FileUtils.mkdir(path);
583 }
584
585 private void createEmptyFolderIgnored() throws Exception {
586 File path = new File(db.getWorkTree(), IGNORED_FOLDER);
587 FileUtils.mkdir(path);
588 writeTrashFile(GITIGNORE, GITIGNORE + "\n" + IGNORED_FOLDER + "/");
589 }
590
591 private void recreateEmptyFolderIgnored() throws Exception {
592 createEmptyFolder();
593 writeTrashFile(GITIGNORE, GITIGNORE + "\n" + FOLDER + "/");
594 }
595
596 private void deleteFolder() throws Exception {
597 deleteTrashFile(FOLDER);
598 }
599
600 private void deleteFolderAndCommit() throws Exception {
601 deleteFolder();
602 commitRm(FOLDER);
603 }
604
605 private void deleteAll() throws Exception {
606 deleteFileInFolder();
607 deleteFolder();
608 }
609
610 private void deleteAllAndCommit() throws Exception {
611 deleteFileInFolderAndCommit();
612 deleteFolderAndCommit();
613 }
614
615 private RevCommit commitAdd() throws Exception {
616 git.add().addFilepattern(".").call();
617 return git.commit().setMessage("commit").call();
618 }
619
620 private RevCommit commitRm(String path) throws Exception {
621 git.rm().addFilepattern(path).call();
622 return git.commit().setMessage("commit").call();
623 }
624
625 private TreeWalk createTreeWalk(RevCommit commit) throws Exception {
626 return createTreeWalk(commit, true, true);
627 }
628
629 private TreeWalk createTreeWalkDishonorIgnores(RevCommit commit)
630 throws Exception {
631 return createTreeWalk(commit, true, false);
632 }
633
634 private TreeWalk createNonRecursiveTreeWalk(RevCommit commit)
635 throws Exception {
636 return createTreeWalk(commit, false, true);
637 }
638
639 private TreeWalk createTreeWalk(RevCommit commit, boolean isRecursive,
640 boolean honorIgnores) throws Exception {
641 TreeWalk treeWalk = new TreeWalk(db);
642 treeWalk.setRecursive(isRecursive);
643 treeWalk.addTree(commit.getTree());
644 treeWalk.addTree(new DirCacheIterator(db.readDirCache()));
645 treeWalk.addTree(new FileTreeIterator(db));
646 if (!honorIgnores)
647 treeWalk.setFilter(new IndexDiffFilter(1, 2, honorIgnores));
648 else
649 treeWalk.setFilter(new IndexDiffFilter(1, 2));
650 return treeWalk;
651 }
652
653 private static void assertPaths(TreeWalk treeWalk, String... paths)
654 throws Exception {
655 for (int i = 0; i < paths.length; i++) {
656 assertTrue(treeWalk.next());
657 assertPath(treeWalk.getPathString(), paths);
658 }
659 assertFalse(treeWalk.next());
660 }
661
662 private static void assertPath(String path, String... paths) {
663 for (String p : paths)
664 if (p.equals(path))
665 return;
666 fail("Expected path '" + path + "' is not returned");
667 }
668 }