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