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
45
46
47 package org.eclipse.jgit.lib;
48
49 import static org.junit.Assert.assertEquals;
50 import static org.junit.Assert.assertFalse;
51 import static org.junit.Assert.assertTrue;
52
53 import java.io.File;
54 import java.io.FileNotFoundException;
55 import java.io.IOException;
56 import java.util.Arrays;
57 import java.util.Collections;
58 import java.util.HashSet;
59 import java.util.TreeSet;
60
61 import org.eclipse.jgit.api.Git;
62 import org.eclipse.jgit.api.MergeResult;
63 import org.eclipse.jgit.api.MergeResult.MergeStatus;
64 import org.eclipse.jgit.api.errors.GitAPIException;
65 import org.eclipse.jgit.dircache.DirCache;
66 import org.eclipse.jgit.dircache.DirCacheBuilder;
67 import org.eclipse.jgit.dircache.DirCacheEditor;
68 import org.eclipse.jgit.dircache.DirCacheEditor.PathEdit;
69 import org.eclipse.jgit.dircache.DirCacheEntry;
70 import org.eclipse.jgit.junit.RepositoryTestCase;
71 import org.eclipse.jgit.lib.CoreConfig.AutoCRLF;
72 import org.eclipse.jgit.lib.IndexDiff.StageState;
73 import org.eclipse.jgit.merge.MergeStrategy;
74 import org.eclipse.jgit.revwalk.RevCommit;
75 import org.eclipse.jgit.storage.file.FileBasedConfig;
76 import org.eclipse.jgit.treewalk.FileTreeIterator;
77 import org.eclipse.jgit.util.IO;
78 import org.junit.Test;
79
80 @SuppressWarnings("deprecation")
81 public class IndexDiffTest extends RepositoryTestCase {
82
83 static PathEdit add(final Repository db, final File workdir,
84 final String path) throws FileNotFoundException, IOException {
85 ObjectInserter inserter = db.newObjectInserter();
86 final File f = new File(workdir, path);
87 final ObjectId id = inserter.insert(Constants.OBJ_BLOB,
88 IO.readFully(f));
89 return new PathEdit(path) {
90 public void apply(DirCacheEntry ent) {
91 ent.setFileMode(FileMode.REGULAR_FILE);
92 ent.setLength(f.length());
93 ent.setObjectId(id);
94 }
95 };
96 }
97
98 @Test
99 public void testAdded() throws IOException {
100 writeTrashFile("file1", "file1");
101 writeTrashFile("dir/subfile", "dir/subfile");
102 Tree tree = new Tree(db);
103 tree.setId(insertTree(tree));
104
105 DirCache index = db.lockDirCache();
106 DirCacheEditor editor = index.editor();
107 editor.add(add(db, trash, "file1"));
108 editor.add(add(db, trash, "dir/subfile"));
109 editor.commit();
110 FileTreeIterator iterator = new FileTreeIterator(db);
111 IndexDiff diff = new IndexDiff(db, tree.getId(), iterator);
112 diff.diff();
113 assertEquals(2, diff.getAdded().size());
114 assertTrue(diff.getAdded().contains("file1"));
115 assertTrue(diff.getAdded().contains("dir/subfile"));
116 assertEquals(0, diff.getChanged().size());
117 assertEquals(0, diff.getModified().size());
118 assertEquals(0, diff.getRemoved().size());
119 assertEquals(Collections.EMPTY_SET, diff.getUntrackedFolders());
120 }
121
122 @Test
123 public void testRemoved() throws IOException {
124 writeTrashFile("file2", "file2");
125 writeTrashFile("dir/file3", "dir/file3");
126
127 Tree tree = new Tree(db);
128 tree.addFile("file2");
129 tree.addFile("dir/file3");
130 assertEquals(2, tree.memberCount());
131 tree.findBlobMember("file2").setId(ObjectId.fromString("30d67d4672d5c05833b7192cc77a79eaafb5c7ad"));
132 Tree tree2 = (Tree) tree.findTreeMember("dir");
133 tree2.findBlobMember("file3").setId(ObjectId.fromString("873fb8d667d05436d728c52b1d7a09528e6eb59b"));
134 tree2.setId(insertTree(tree2));
135 tree.setId(insertTree(tree));
136
137 FileTreeIterator iterator = new FileTreeIterator(db);
138 IndexDiff diff = new IndexDiff(db, tree.getId(), iterator);
139 diff.diff();
140 assertEquals(2, diff.getRemoved().size());
141 assertTrue(diff.getRemoved().contains("file2"));
142 assertTrue(diff.getRemoved().contains("dir/file3"));
143 assertEquals(0, diff.getChanged().size());
144 assertEquals(0, diff.getModified().size());
145 assertEquals(0, diff.getAdded().size());
146 assertEquals(Collections.EMPTY_SET, diff.getUntrackedFolders());
147 }
148
149 @Test
150 public void testModified() throws IOException, GitAPIException {
151
152 writeTrashFile("file2", "file2");
153 writeTrashFile("dir/file3", "dir/file3");
154
155 Git git = new Git(db);
156 git.add().addFilepattern("file2").addFilepattern("dir/file3").call();
157
158 writeTrashFile("dir/file3", "changed");
159
160 Tree tree = new Tree(db);
161 tree.addFile("file2").setId(ObjectId.fromString("0123456789012345678901234567890123456789"));
162 tree.addFile("dir/file3").setId(ObjectId.fromString("0123456789012345678901234567890123456789"));
163 assertEquals(2, tree.memberCount());
164
165 Tree tree2 = (Tree) tree.findTreeMember("dir");
166 tree2.setId(insertTree(tree2));
167 tree.setId(insertTree(tree));
168 FileTreeIterator iterator = new FileTreeIterator(db);
169 IndexDiff diff = new IndexDiff(db, tree.getId(), iterator);
170 diff.diff();
171 assertEquals(2, diff.getChanged().size());
172 assertTrue(diff.getChanged().contains("file2"));
173 assertTrue(diff.getChanged().contains("dir/file3"));
174 assertEquals(1, diff.getModified().size());
175 assertTrue(diff.getModified().contains("dir/file3"));
176 assertEquals(0, diff.getAdded().size());
177 assertEquals(0, diff.getRemoved().size());
178 assertEquals(0, diff.getMissing().size());
179 assertEquals(Collections.EMPTY_SET, diff.getUntrackedFolders());
180 }
181
182 @Test
183 public void testConflicting() throws Exception {
184 Git git = new Git(db);
185
186 writeTrashFile("a", "1\na\n3\n");
187 writeTrashFile("b", "1\nb\n3\n");
188 git.add().addFilepattern("a").addFilepattern("b").call();
189 RevCommit initialCommit = git.commit().setMessage("initial").call();
190
191
192 createBranch(initialCommit, "refs/heads/side");
193 checkoutBranch("refs/heads/side");
194 writeTrashFile("a", "1\na(side)\n3\n");
195 writeTrashFile("b", "1\nb\n3\n(side)");
196 git.add().addFilepattern("a").addFilepattern("b").call();
197 RevCommit secondCommit = git.commit().setMessage("side").call();
198
199
200 checkoutBranch("refs/heads/master");
201 writeTrashFile("a", "1\na(main)\n3\n");
202 git.add().addFilepattern("a").call();
203 git.commit().setMessage("main").call();
204
205
206 MergeResult result = git.merge().include(secondCommit.getId())
207 .setStrategy(MergeStrategy.RESOLVE).call();
208 assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());
209
210 FileTreeIterator iterator = new FileTreeIterator(db);
211 IndexDiff diff = new IndexDiff(db, Constants.HEAD, iterator);
212 diff.diff();
213
214 assertEquals("[b]",
215 new TreeSet<String>(diff.getChanged()).toString());
216 assertEquals("[]", diff.getAdded().toString());
217 assertEquals("[]", diff.getRemoved().toString());
218 assertEquals("[]", diff.getMissing().toString());
219 assertEquals("[]", diff.getModified().toString());
220 assertEquals("[a]", diff.getConflicting().toString());
221 assertEquals(StageState.BOTH_MODIFIED,
222 diff.getConflictingStageStates().get("a"));
223 assertEquals(Collections.EMPTY_SET, diff.getUntrackedFolders());
224 }
225
226 @Test
227 public void testConflictingDeletedAndModified() throws Exception {
228 Git git = new Git(db);
229
230 writeTrashFile("a", "1\na\n3\n");
231 writeTrashFile("b", "1\nb\n3\n");
232 git.add().addFilepattern("a").addFilepattern("b").call();
233 RevCommit initialCommit = git.commit().setMessage("initial").call();
234
235
236 createBranch(initialCommit, "refs/heads/side");
237 checkoutBranch("refs/heads/side");
238 git.rm().addFilepattern("a").call();
239 RevCommit secondCommit = git.commit().setMessage("side").call();
240
241
242 checkoutBranch("refs/heads/master");
243 writeTrashFile("a", "1\na(main)\n3\n");
244 git.add().addFilepattern("a").call();
245 git.commit().setMessage("main").call();
246
247
248 MergeResult result = git.merge().include(secondCommit.getId())
249 .setStrategy(MergeStrategy.RESOLVE).call();
250 assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());
251
252 FileTreeIterator iterator = new FileTreeIterator(db);
253 IndexDiff diff = new IndexDiff(db, Constants.HEAD, iterator);
254 diff.diff();
255
256 assertEquals("[]", new TreeSet<String>(diff.getChanged()).toString());
257 assertEquals("[]", diff.getAdded().toString());
258 assertEquals("[]", diff.getRemoved().toString());
259 assertEquals("[]", diff.getMissing().toString());
260 assertEquals("[]", diff.getModified().toString());
261 assertEquals("[a]", diff.getConflicting().toString());
262 assertEquals(StageState.DELETED_BY_THEM,
263 diff.getConflictingStageStates().get("a"));
264 assertEquals(Collections.EMPTY_SET, diff.getUntrackedFolders());
265 }
266
267 @Test
268 public void testConflictingFromMultipleCreations() throws Exception {
269 Git git = new Git(db);
270
271 writeTrashFile("a", "1\na\n3\n");
272 git.add().addFilepattern("a").call();
273 RevCommit initialCommit = git.commit().setMessage("initial").call();
274
275 createBranch(initialCommit, "refs/heads/side");
276 checkoutBranch("refs/heads/side");
277
278 writeTrashFile("b", "1\nb(side)\n3\n");
279 git.add().addFilepattern("b").call();
280 RevCommit secondCommit = git.commit().setMessage("side").call();
281
282 checkoutBranch("refs/heads/master");
283
284 writeTrashFile("b", "1\nb(main)\n3\n");
285 git.add().addFilepattern("b").call();
286 git.commit().setMessage("main").call();
287
288 MergeResult result = git.merge().include(secondCommit.getId())
289 .setStrategy(MergeStrategy.RESOLVE).call();
290 assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());
291
292 FileTreeIterator iterator = new FileTreeIterator(db);
293 IndexDiff diff = new IndexDiff(db, Constants.HEAD, iterator);
294 diff.diff();
295
296 assertEquals("[]", new TreeSet<String>(diff.getChanged()).toString());
297 assertEquals("[]", diff.getAdded().toString());
298 assertEquals("[]", diff.getRemoved().toString());
299 assertEquals("[]", diff.getMissing().toString());
300 assertEquals("[]", diff.getModified().toString());
301 assertEquals("[b]", diff.getConflicting().toString());
302 assertEquals(Collections.EMPTY_SET, diff.getUntrackedFolders());
303 }
304
305 @Test
306 public void testUnchangedSimple() throws IOException, GitAPIException {
307 writeTrashFile("a.b", "a.b");
308 writeTrashFile("a.c", "a.c");
309 writeTrashFile("a=c", "a=c");
310 writeTrashFile("a=d", "a=d");
311 Git git = new Git(db);
312 git.add().addFilepattern("a.b").call();
313 git.add().addFilepattern("a.c").call();
314 git.add().addFilepattern("a=c").call();
315 git.add().addFilepattern("a=d").call();
316
317 Tree tree = new Tree(db);
318
319 tree.addFile("a.b").setId(ObjectId.fromString("f6f28df96c2b40c951164286e08be7c38ec74851"));
320 tree.addFile("a.c").setId(ObjectId.fromString("6bc0e647512d2a0bef4f26111e484dc87df7f5ca"));
321 tree.addFile("a=c").setId(ObjectId.fromString("06022365ddbd7fb126761319633bf73517770714"));
322 tree.addFile("a=d").setId(ObjectId.fromString("fa6414df3da87840700e9eeb7fc261dd77ccd5c2"));
323
324 tree.setId(insertTree(tree));
325
326 FileTreeIterator iterator = new FileTreeIterator(db);
327 IndexDiff diff = new IndexDiff(db, tree.getId(), iterator);
328 diff.diff();
329 assertEquals(0, diff.getChanged().size());
330 assertEquals(0, diff.getAdded().size());
331 assertEquals(0, diff.getRemoved().size());
332 assertEquals(0, diff.getMissing().size());
333 assertEquals(0, diff.getModified().size());
334 assertEquals(Collections.EMPTY_SET, diff.getUntrackedFolders());
335 }
336
337
338
339
340
341
342
343
344 @Test
345 public void testUnchangedComplex() throws IOException, GitAPIException {
346 Git git = new Git(db);
347 writeTrashFile("a.b", "a.b");
348 writeTrashFile("a.c", "a.c");
349 writeTrashFile("a/b.b/b", "a/b.b/b");
350 writeTrashFile("a/b", "a/b");
351 writeTrashFile("a/c", "a/c");
352 writeTrashFile("a=c", "a=c");
353 writeTrashFile("a=d", "a=d");
354 git.add().addFilepattern("a.b").addFilepattern("a.c")
355 .addFilepattern("a/b.b/b").addFilepattern("a/b")
356 .addFilepattern("a/c").addFilepattern("a=c")
357 .addFilepattern("a=d").call();
358
359 Tree tree = new Tree(db);
360
361 tree.addFile("a.b").setId(ObjectId.fromString("f6f28df96c2b40c951164286e08be7c38ec74851"));
362 tree.addFile("a.c").setId(ObjectId.fromString("6bc0e647512d2a0bef4f26111e484dc87df7f5ca"));
363 tree.addFile("a/b.b/b").setId(ObjectId.fromString("8d840bd4e2f3a48ff417c8e927d94996849933fd"));
364 tree.addFile("a/b").setId(ObjectId.fromString("db89c972fc57862eae378f45b74aca228037d415"));
365 tree.addFile("a/c").setId(ObjectId.fromString("52ad142a008aeb39694bafff8e8f1be75ed7f007"));
366 tree.addFile("a=c").setId(ObjectId.fromString("06022365ddbd7fb126761319633bf73517770714"));
367 tree.addFile("a=d").setId(ObjectId.fromString("fa6414df3da87840700e9eeb7fc261dd77ccd5c2"));
368
369 Tree tree3 = (Tree) tree.findTreeMember("a/b.b");
370 tree3.setId(insertTree(tree3));
371 Tree tree2 = (Tree) tree.findTreeMember("a");
372 tree2.setId(insertTree(tree2));
373 tree.setId(insertTree(tree));
374
375 FileTreeIterator iterator = new FileTreeIterator(db);
376 IndexDiff diff = new IndexDiff(db, tree.getId(), iterator);
377 diff.diff();
378 assertEquals(0, diff.getChanged().size());
379 assertEquals(0, diff.getAdded().size());
380 assertEquals(0, diff.getRemoved().size());
381 assertEquals(0, diff.getMissing().size());
382 assertEquals(0, diff.getModified().size());
383 assertEquals(Collections.EMPTY_SET, diff.getUntrackedFolders());
384 }
385
386 private ObjectId insertTree(Tree tree) throws IOException {
387 try (ObjectInserter oi = db.newObjectInserter()) {
388 ObjectId id = oi.insert(Constants.OBJ_TREE, tree.format());
389 oi.flush();
390 return id;
391 }
392 }
393
394
395
396
397
398
399
400 @Test
401 public void testRemovedUntracked() throws Exception{
402 Git git = new Git(db);
403 String path = "file";
404 writeTrashFile(path, "content");
405 git.add().addFilepattern(path).call();
406 git.commit().setMessage("commit").call();
407 removeFromIndex(path);
408 FileTreeIterator iterator = new FileTreeIterator(db);
409 IndexDiff diff = new IndexDiff(db, Constants.HEAD, iterator);
410 diff.diff();
411 assertTrue(diff.getRemoved().contains(path));
412 assertTrue(diff.getUntracked().contains(path));
413 assertEquals(Collections.EMPTY_SET, diff.getUntrackedFolders());
414 }
415
416
417
418
419
420 @Test
421 public void testUntrackedFolders() throws Exception {
422 Git git = new Git(db);
423
424 IndexDiff diff = new IndexDiff(db, Constants.HEAD,
425 new FileTreeIterator(db));
426 diff.diff();
427 assertEquals(Collections.EMPTY_SET, diff.getUntrackedFolders());
428
429 writeTrashFile("readme", "");
430 writeTrashFile("src/com/A.java", "");
431 writeTrashFile("src/com/B.java", "");
432 writeTrashFile("src/org/A.java", "");
433 writeTrashFile("src/org/B.java", "");
434 writeTrashFile("target/com/A.java", "");
435 writeTrashFile("target/com/B.java", "");
436 writeTrashFile("target/org/A.java", "");
437 writeTrashFile("target/org/B.java", "");
438
439 git.add().addFilepattern("src").addFilepattern("readme").call();
440 git.commit().setMessage("initial").call();
441
442 diff = new IndexDiff(db, Constants.HEAD,
443 new FileTreeIterator(db));
444 diff.diff();
445 assertEquals(new HashSet<String>(Arrays.asList("target")),
446 diff.getUntrackedFolders());
447
448 writeTrashFile("src/tst/A.java", "");
449 writeTrashFile("src/tst/B.java", "");
450
451 diff = new IndexDiff(db, Constants.HEAD, new FileTreeIterator(db));
452 diff.diff();
453 assertEquals(new HashSet<String>(Arrays.asList("target", "src/tst")),
454 diff.getUntrackedFolders());
455
456 git.rm().addFilepattern("src/com/B.java").addFilepattern("src/org")
457 .call();
458 git.commit().setMessage("second").call();
459 writeTrashFile("src/org/C.java", "");
460
461 diff = new IndexDiff(db, Constants.HEAD, new FileTreeIterator(db));
462 diff.diff();
463 assertEquals(
464 new HashSet<String>(Arrays.asList("src/org", "src/tst",
465 "target")),
466 diff.getUntrackedFolders());
467 }
468
469
470
471
472
473
474 @Test
475 public void testUntrackedNotIgnoredFolders() throws Exception {
476 Git git = new Git(db);
477
478 IndexDiff diff = new IndexDiff(db, Constants.HEAD,
479 new FileTreeIterator(db));
480 diff.diff();
481 assertEquals(Collections.EMPTY_SET, diff.getUntrackedFolders());
482
483 writeTrashFile("readme", "");
484 writeTrashFile("sr/com/X.java", "");
485 writeTrashFile("src/com/A.java", "");
486 writeTrashFile("src/org/B.java", "");
487 writeTrashFile("srcs/org/Y.java", "");
488 writeTrashFile("target/com/A.java", "");
489 writeTrashFile("target/org/B.java", "");
490 writeTrashFile(".gitignore", "/target\n/sr");
491
492 git.add().addFilepattern("readme").addFilepattern(".gitignore")
493 .addFilepattern("srcs/").call();
494 git.commit().setMessage("initial").call();
495
496 diff = new IndexDiff(db, Constants.HEAD, new FileTreeIterator(db));
497 diff.diff();
498 assertEquals(new HashSet<String>(Arrays.asList("src")),
499 diff.getUntrackedFolders());
500
501 git.add().addFilepattern("src").call();
502 writeTrashFile("sr/com/X1.java", "");
503 writeTrashFile("src/tst/A.java", "");
504 writeTrashFile("src/tst/B.java", "");
505 writeTrashFile("srcs/com/Y1.java", "");
506 deleteTrashFile(".gitignore");
507
508 diff = new IndexDiff(db, Constants.HEAD, new FileTreeIterator(db));
509 diff.diff();
510 assertEquals(
511 new HashSet<String>(Arrays.asList("srcs/com", "sr", "src/tst",
512 "target")),
513 diff.getUntrackedFolders());
514 }
515
516 @Test
517 public void testAssumeUnchanged() throws Exception {
518 Git git = new Git(db);
519 String path = "file";
520 writeTrashFile(path, "content");
521 git.add().addFilepattern(path).call();
522 String path2 = "file2";
523 writeTrashFile(path2, "content");
524 String path3 = "file3";
525 writeTrashFile(path3, "some content");
526 git.add().addFilepattern(path2).addFilepattern(path3).call();
527 git.commit().setMessage("commit").call();
528 assumeUnchanged(path2);
529 assumeUnchanged(path3);
530 writeTrashFile(path, "more content");
531 deleteTrashFile(path3);
532
533 FileTreeIterator iterator = new FileTreeIterator(db);
534 IndexDiff diff = new IndexDiff(db, Constants.HEAD, iterator);
535 diff.diff();
536 assertEquals(2, diff.getAssumeUnchanged().size());
537 assertEquals(1, diff.getModified().size());
538 assertEquals(0, diff.getChanged().size());
539 assertTrue(diff.getAssumeUnchanged().contains("file2"));
540 assertTrue(diff.getAssumeUnchanged().contains("file3"));
541 assertTrue(diff.getModified().contains("file"));
542
543 git.add().addFilepattern(".").call();
544
545 iterator = new FileTreeIterator(db);
546 diff = new IndexDiff(db, Constants.HEAD, iterator);
547 diff.diff();
548 assertEquals(2, diff.getAssumeUnchanged().size());
549 assertEquals(0, diff.getModified().size());
550 assertEquals(1, diff.getChanged().size());
551 assertTrue(diff.getAssumeUnchanged().contains("file2"));
552 assertTrue(diff.getAssumeUnchanged().contains("file3"));
553 assertTrue(diff.getChanged().contains("file"));
554 assertEquals(Collections.EMPTY_SET, diff.getUntrackedFolders());
555 }
556
557 @Test
558 public void testStageState() throws IOException {
559 final int base = DirCacheEntry.STAGE_1;
560 final int ours = DirCacheEntry.STAGE_2;
561 final int theirs = DirCacheEntry.STAGE_3;
562 verifyStageState(StageState.BOTH_DELETED, base);
563 verifyStageState(StageState.DELETED_BY_THEM, ours, base);
564 verifyStageState(StageState.DELETED_BY_US, base, theirs);
565 verifyStageState(StageState.BOTH_MODIFIED, base, ours, theirs);
566 verifyStageState(StageState.ADDED_BY_US, ours);
567 verifyStageState(StageState.BOTH_ADDED, ours, theirs);
568 verifyStageState(StageState.ADDED_BY_THEM, theirs);
569
570 assertTrue(StageState.BOTH_DELETED.hasBase());
571 assertFalse(StageState.BOTH_DELETED.hasOurs());
572 assertFalse(StageState.BOTH_DELETED.hasTheirs());
573 assertFalse(StageState.BOTH_ADDED.hasBase());
574 assertTrue(StageState.BOTH_ADDED.hasOurs());
575 assertTrue(StageState.BOTH_ADDED.hasTheirs());
576 }
577
578 @Test
579 public void testStageState_mergeAndReset_bug() throws Exception {
580 Git git = new Git(db);
581
582 writeTrashFile("a", "content");
583 git.add().addFilepattern("a").call();
584 RevCommit initialCommit = git.commit().setMessage("initial commit")
585 .call();
586
587
588 final String branchName = Constants.R_HEADS + "branch";
589 createBranch(initialCommit, branchName);
590 checkoutBranch(branchName);
591 writeTrashFile("b", "second file content - branch");
592 git.add().addFilepattern("b").call();
593 RevCommit branchCommit = git.commit().setMessage("branch commit")
594 .call();
595
596
597 checkoutBranch(Constants.R_HEADS + Constants.MASTER);
598 writeTrashFile("b", "second file content - master");
599 git.add().addFilepattern("b").call();
600 git.commit().setMessage("master commit").call();
601
602
603 MergeResult result = git.merge().include(branchCommit).call();
604 assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());
605
606 FileTreeIterator iterator = new FileTreeIterator(db);
607 IndexDiff diff = new IndexDiff(db, Constants.HEAD, iterator);
608 diff.diff();
609
610 assertTrue(diff.getChanged().isEmpty());
611 assertTrue(diff.getAdded().isEmpty());
612 assertTrue(diff.getRemoved().isEmpty());
613 assertTrue(diff.getMissing().isEmpty());
614 assertTrue(diff.getModified().isEmpty());
615 assertEquals(1, diff.getConflicting().size());
616 assertTrue(diff.getConflicting().contains("b"));
617 assertEquals(StageState.BOTH_ADDED, diff.getConflictingStageStates()
618 .get("b"));
619 assertTrue(diff.getUntrackedFolders().isEmpty());
620
621
622 writeTrashFile("b", "second file content - master");
623
624
625 iterator = new FileTreeIterator(db);
626 diff = new IndexDiff(db, Constants.HEAD, iterator);
627 diff.diff();
628
629 assertTrue(diff.getChanged().isEmpty());
630 assertTrue(diff.getAdded().isEmpty());
631 assertTrue(diff.getRemoved().isEmpty());
632 assertTrue(diff.getMissing().isEmpty());
633 assertTrue(diff.getModified().isEmpty());
634 assertEquals(1, diff.getConflicting().size());
635 assertTrue(diff.getConflicting().contains("b"));
636 assertEquals(StageState.BOTH_ADDED, diff.getConflictingStageStates()
637 .get("b"));
638 assertTrue(diff.getUntrackedFolders().isEmpty());
639 }
640
641 @Test
642 public void testStageState_simulated_bug() throws Exception {
643 Git git = new Git(db);
644
645 writeTrashFile("a", "content");
646 git.add().addFilepattern("a").call();
647 RevCommit initialCommit = git.commit().setMessage("initial commit")
648 .call();
649
650
651 final String branchName = Constants.R_HEADS + "branch";
652 createBranch(initialCommit, branchName);
653 checkoutBranch(branchName);
654 writeTrashFile("b", "second file content - branch");
655 git.add().addFilepattern("b").call();
656 git.commit().setMessage("branch commit")
657 .call();
658
659
660 checkoutBranch(Constants.R_HEADS + Constants.MASTER);
661 writeTrashFile("b", "second file content - master");
662 git.add().addFilepattern("b").call();
663 git.commit().setMessage("master commit").call();
664
665
666 DirCacheBuilder builder = db.lockDirCache().builder();
667 DirCacheEntry entry = createEntry("a", FileMode.REGULAR_FILE, 0,
668 "content");
669 builder.add(entry);
670 entry = createEntry("b", FileMode.REGULAR_FILE, 2,
671 "second file content - master");
672 builder.add(entry);
673 entry = createEntry("b", FileMode.REGULAR_FILE, 3,
674 "second file content - branch");
675 builder.add(entry);
676 builder.commit();
677
678 FileTreeIterator iterator = new FileTreeIterator(db);
679 IndexDiff diff = new IndexDiff(db, Constants.HEAD, iterator);
680 diff.diff();
681
682 assertTrue(diff.getChanged().isEmpty());
683 assertTrue(diff.getAdded().isEmpty());
684 assertTrue(diff.getRemoved().isEmpty());
685 assertTrue(diff.getMissing().isEmpty());
686 assertTrue(diff.getModified().isEmpty());
687 assertEquals(1, diff.getConflicting().size());
688 assertTrue(diff.getConflicting().contains("b"));
689 assertEquals(StageState.BOTH_ADDED, diff.getConflictingStageStates()
690 .get("b"));
691 assertTrue(diff.getUntrackedFolders().isEmpty());
692 }
693
694 @Test
695 public void testAutoCRLFInput() throws Exception {
696 Git git = new Git(db);
697 FileBasedConfig config = db.getConfig();
698
699
700 config.setEnum(ConfigConstants.CONFIG_CORE_SECTION, null,
701 ConfigConstants.CONFIG_KEY_AUTOCRLF, AutoCRLF.FALSE);
702 config.save();
703
704
705 writeTrashFile("crlf.txt", "this\r\ncontains\r\ncrlf\r\n");
706 git.add().addFilepattern("crlf.txt").call();
707 git.commit().setMessage("Add crlf.txt").call();
708
709
710 config.setEnum(ConfigConstants.CONFIG_CORE_SECTION, null,
711 ConfigConstants.CONFIG_KEY_AUTOCRLF, AutoCRLF.INPUT);
712 config.save();
713
714 FileTreeIterator iterator = new FileTreeIterator(db);
715 IndexDiff diff = new IndexDiff(db, Constants.HEAD, iterator);
716 diff.diff();
717
718 assertTrue(
719 "Expected no modified files, but there were: "
720 + diff.getModified(), diff.getModified().isEmpty());
721 }
722
723 private void verifyStageState(StageState expected, int... stages)
724 throws IOException {
725 DirCacheBuilder builder = db.lockDirCache().builder();
726 for (int stage : stages) {
727 DirCacheEntry entry = createEntry("a", FileMode.REGULAR_FILE,
728 stage, "content");
729 builder.add(entry);
730 }
731 builder.commit();
732
733 IndexDiff diff = new IndexDiff(db, Constants.HEAD,
734 new FileTreeIterator(db));
735 diff.diff();
736
737 assertEquals(
738 "Conflict for entries in stages " + Arrays.toString(stages),
739 expected, diff.getConflictingStageStates().get("a"));
740 }
741
742 private void removeFromIndex(String path) throws IOException {
743 final DirCache dirc = db.lockDirCache();
744 final DirCacheEditor edit = dirc.editor();
745 edit.add(new DirCacheEditor.DeletePath(path));
746 if (!edit.commit())
747 throw new IOException("could not commit");
748 }
749
750 private void assumeUnchanged(String path) throws IOException {
751 final DirCache dirc = db.lockDirCache();
752 final DirCacheEntry ent = dirc.getEntry(path);
753 if (ent != null)
754 ent.setAssumeValid(true);
755 dirc.write();
756 if (!dirc.commit())
757 throw new IOException("could not commit");
758 }
759
760 }