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
478 @Test
479 public void testUntrackedNotIgnoredFolders() throws Exception {
480 try (Git git = new Git(db)) {
481 IndexDiff diff = new IndexDiff(db, Constants.HEAD,
482 new FileTreeIterator(db));
483 diff.diff();
484 assertEquals(Collections.EMPTY_SET, diff.getUntrackedFolders());
485
486 writeTrashFile("readme", "");
487 writeTrashFile("sr/com/X.java", "");
488 writeTrashFile("src/com/A.java", "");
489 writeTrashFile("src/org/B.java", "");
490 writeTrashFile("srcs/org/Y.java", "");
491 writeTrashFile("target/com/A.java", "");
492 writeTrashFile("target/org/B.java", "");
493 writeTrashFile(".gitignore", "/target\n/sr");
494
495 git.add().addFilepattern("readme").addFilepattern(".gitignore")
496 .addFilepattern("srcs/").call();
497 git.commit().setMessage("initial").call();
498
499 diff = new IndexDiff(db, Constants.HEAD, new FileTreeIterator(db));
500 diff.diff();
501 assertEquals(new HashSet<>(Arrays.asList("src")),
502 diff.getUntrackedFolders());
503 assertEquals(new HashSet<>(Arrays.asList("sr", "target")),
504 diff.getIgnoredNotInIndex());
505
506 git.add().addFilepattern("src").call();
507 writeTrashFile("sr/com/X1.java", "");
508 writeTrashFile("src/tst/A.java", "");
509 writeTrashFile("src/tst/B.java", "");
510 writeTrashFile("srcs/com/Y1.java", "");
511 deleteTrashFile(".gitignore");
512
513 diff = new IndexDiff(db, Constants.HEAD, new FileTreeIterator(db));
514 diff.diff();
515 assertEquals(
516 new HashSet<>(Arrays.asList("srcs/com", "sr", "src/tst",
517 "target")),
518 diff.getUntrackedFolders());
519 }
520 }
521
522 @Test
523 public void testAssumeUnchanged() throws Exception {
524 try (Git git = new Git(db)) {
525 String path = "file";
526 writeTrashFile(path, "content");
527 git.add().addFilepattern(path).call();
528 String path2 = "file2";
529 writeTrashFile(path2, "content");
530 String path3 = "file3";
531 writeTrashFile(path3, "some content");
532 git.add().addFilepattern(path2).addFilepattern(path3).call();
533 git.commit().setMessage("commit").call();
534 assumeUnchanged(path2);
535 assumeUnchanged(path3);
536 writeTrashFile(path, "more content");
537 deleteTrashFile(path3);
538
539 FileTreeIterator iterator = new FileTreeIterator(db);
540 IndexDiff diff = new IndexDiff(db, Constants.HEAD, iterator);
541 diff.diff();
542 assertEquals(2, diff.getAssumeUnchanged().size());
543 assertEquals(1, diff.getModified().size());
544 assertEquals(0, diff.getChanged().size());
545 assertTrue(diff.getAssumeUnchanged().contains("file2"));
546 assertTrue(diff.getAssumeUnchanged().contains("file3"));
547 assertTrue(diff.getModified().contains("file"));
548
549 git.add().addFilepattern(".").call();
550
551 iterator = new FileTreeIterator(db);
552 diff = new IndexDiff(db, Constants.HEAD, iterator);
553 diff.diff();
554 assertEquals(2, diff.getAssumeUnchanged().size());
555 assertEquals(0, diff.getModified().size());
556 assertEquals(1, diff.getChanged().size());
557 assertTrue(diff.getAssumeUnchanged().contains("file2"));
558 assertTrue(diff.getAssumeUnchanged().contains("file3"));
559 assertTrue(diff.getChanged().contains("file"));
560 assertEquals(Collections.EMPTY_SET, diff.getUntrackedFolders());
561 }
562 }
563
564 @Test
565 public void testStageState() throws IOException {
566 final int base = DirCacheEntry.STAGE_1;
567 final int ours = DirCacheEntry.STAGE_2;
568 final int theirs = DirCacheEntry.STAGE_3;
569 verifyStageState(StageState.BOTH_DELETED, base);
570 verifyStageState(StageState.DELETED_BY_THEM, ours, base);
571 verifyStageState(StageState.DELETED_BY_US, base, theirs);
572 verifyStageState(StageState.BOTH_MODIFIED, base, ours, theirs);
573 verifyStageState(StageState.ADDED_BY_US, ours);
574 verifyStageState(StageState.BOTH_ADDED, ours, theirs);
575 verifyStageState(StageState.ADDED_BY_THEM, theirs);
576
577 assertTrue(StageState.BOTH_DELETED.hasBase());
578 assertFalse(StageState.BOTH_DELETED.hasOurs());
579 assertFalse(StageState.BOTH_DELETED.hasTheirs());
580 assertFalse(StageState.BOTH_ADDED.hasBase());
581 assertTrue(StageState.BOTH_ADDED.hasOurs());
582 assertTrue(StageState.BOTH_ADDED.hasTheirs());
583 }
584
585 @Test
586 public void testStageState_mergeAndReset_bug() throws Exception {
587 try (Git git = new Git(db)) {
588 writeTrashFile("a", "content");
589 git.add().addFilepattern("a").call();
590 RevCommit initialCommit = git.commit().setMessage("initial commit")
591 .call();
592
593
594 final String branchName = Constants.R_HEADS + "branch";
595 createBranch(initialCommit, branchName);
596 checkoutBranch(branchName);
597 writeTrashFile("b", "second file content - branch");
598 git.add().addFilepattern("b").call();
599 RevCommit branchCommit = git.commit().setMessage("branch commit")
600 .call();
601
602
603 checkoutBranch(Constants.R_HEADS + Constants.MASTER);
604 writeTrashFile("b", "second file content - master");
605 git.add().addFilepattern("b").call();
606 git.commit().setMessage("master commit").call();
607
608
609 MergeResult result = git.merge().include(branchCommit).call();
610 assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());
611
612 FileTreeIterator iterator = new FileTreeIterator(db);
613 IndexDiff diff = new IndexDiff(db, Constants.HEAD, iterator);
614 diff.diff();
615
616 assertTrue(diff.getChanged().isEmpty());
617 assertTrue(diff.getAdded().isEmpty());
618 assertTrue(diff.getRemoved().isEmpty());
619 assertTrue(diff.getMissing().isEmpty());
620 assertTrue(diff.getModified().isEmpty());
621 assertEquals(1, diff.getConflicting().size());
622 assertTrue(diff.getConflicting().contains("b"));
623 assertEquals(StageState.BOTH_ADDED, diff.getConflictingStageStates()
624 .get("b"));
625 assertTrue(diff.getUntrackedFolders().isEmpty());
626
627
628 writeTrashFile("b", "second file content - master");
629
630
631 iterator = new FileTreeIterator(db);
632 diff = new IndexDiff(db, Constants.HEAD, iterator);
633 diff.diff();
634
635 assertTrue(diff.getChanged().isEmpty());
636 assertTrue(diff.getAdded().isEmpty());
637 assertTrue(diff.getRemoved().isEmpty());
638 assertTrue(diff.getMissing().isEmpty());
639 assertTrue(diff.getModified().isEmpty());
640 assertEquals(1, diff.getConflicting().size());
641 assertTrue(diff.getConflicting().contains("b"));
642 assertEquals(StageState.BOTH_ADDED, diff.getConflictingStageStates()
643 .get("b"));
644 assertTrue(diff.getUntrackedFolders().isEmpty());
645 }
646 }
647
648 @Test
649 public void testStageState_simulated_bug() throws Exception {
650 try (Git git = new Git(db)) {
651 writeTrashFile("a", "content");
652 git.add().addFilepattern("a").call();
653 RevCommit initialCommit = git.commit().setMessage("initial commit")
654 .call();
655
656
657 final String branchName = Constants.R_HEADS + "branch";
658 createBranch(initialCommit, branchName);
659 checkoutBranch(branchName);
660 writeTrashFile("b", "second file content - branch");
661 git.add().addFilepattern("b").call();
662 git.commit().setMessage("branch commit")
663 .call();
664
665
666 checkoutBranch(Constants.R_HEADS + Constants.MASTER);
667 writeTrashFile("b", "second file content - master");
668 git.add().addFilepattern("b").call();
669 git.commit().setMessage("master commit").call();
670
671
672 DirCacheBuilder builder = db.lockDirCache().builder();
673 DirCacheEntry entry = createEntry("a", FileMode.REGULAR_FILE, 0,
674 "content");
675 builder.add(entry);
676 entry = createEntry("b", FileMode.REGULAR_FILE, 2,
677 "second file content - master");
678 builder.add(entry);
679 entry = createEntry("b", FileMode.REGULAR_FILE, 3,
680 "second file content - branch");
681 builder.add(entry);
682 builder.commit();
683
684 FileTreeIterator iterator = new FileTreeIterator(db);
685 IndexDiff diff = new IndexDiff(db, Constants.HEAD, iterator);
686 diff.diff();
687
688 assertTrue(diff.getChanged().isEmpty());
689 assertTrue(diff.getAdded().isEmpty());
690 assertTrue(diff.getRemoved().isEmpty());
691 assertTrue(diff.getMissing().isEmpty());
692 assertTrue(diff.getModified().isEmpty());
693 assertEquals(1, diff.getConflicting().size());
694 assertTrue(diff.getConflicting().contains("b"));
695 assertEquals(StageState.BOTH_ADDED, diff.getConflictingStageStates()
696 .get("b"));
697 assertTrue(diff.getUntrackedFolders().isEmpty());
698 }
699 }
700
701 @Test
702 public void testAutoCRLFInput() throws Exception {
703 try (Git git = new Git(db)) {
704 FileBasedConfig config = db.getConfig();
705
706
707 config.setEnum(ConfigConstants.CONFIG_CORE_SECTION, null,
708 ConfigConstants.CONFIG_KEY_AUTOCRLF, AutoCRLF.FALSE);
709 config.save();
710
711
712 writeTrashFile("crlf.txt", "this\r\ncontains\r\ncrlf\r\n");
713 git.add().addFilepattern("crlf.txt").call();
714 git.commit().setMessage("Add crlf.txt").call();
715
716
717 config.setEnum(ConfigConstants.CONFIG_CORE_SECTION, null,
718 ConfigConstants.CONFIG_KEY_AUTOCRLF, AutoCRLF.INPUT);
719 config.save();
720
721 FileTreeIterator iterator = new FileTreeIterator(db);
722 IndexDiff diff = new IndexDiff(db, Constants.HEAD, iterator);
723 diff.diff();
724
725 assertTrue(
726 "Expected no modified files, but there were: "
727 + diff.getModified(), diff.getModified().isEmpty());
728 }
729 }
730
731 private void verifyStageState(StageState expected, int... stages)
732 throws IOException {
733 DirCacheBuilder builder = db.lockDirCache().builder();
734 for (int stage : stages) {
735 DirCacheEntry entry = createEntry("a", FileMode.REGULAR_FILE,
736 stage, "content");
737 builder.add(entry);
738 }
739 builder.commit();
740
741 IndexDiff diff = new IndexDiff(db, Constants.HEAD,
742 new FileTreeIterator(db));
743 diff.diff();
744
745 assertEquals(
746 "Conflict for entries in stages " + Arrays.toString(stages),
747 expected, diff.getConflictingStageStates().get("a"));
748 }
749
750 private void removeFromIndex(String path) throws IOException {
751 final DirCache dirc = db.lockDirCache();
752 final DirCacheEditor edit = dirc.editor();
753 edit.add(new DirCacheEditor.DeletePath(path));
754 if (!edit.commit())
755 throw new IOException("could not commit");
756 }
757
758 private void assumeUnchanged(String path) throws IOException {
759 final DirCache dirc = db.lockDirCache();
760 final DirCacheEntry ent = dirc.getEntry(path);
761 if (ent != null)
762 ent.setAssumeValid(true);
763 dirc.write();
764 if (!dirc.commit())
765 throw new IOException("could not commit");
766 }
767
768 }