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