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