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 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 Git git = new Git(db);
153 git.add().addFilepattern("file2").addFilepattern("dir/file3").call();
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 Git git = new Git(db);
182
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 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 Git git = new Git(db);
226
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 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 Git git = new Git(db);
267
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 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 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 TreeFormatter tree = new TreeFormatter();
315
316 tree.append("a.b", FileMode.REGULAR_FILE, ObjectId.fromString("f6f28df96c2b40c951164286e08be7c38ec74851"));
317 tree.append("a.c", FileMode.REGULAR_FILE, ObjectId.fromString("6bc0e647512d2a0bef4f26111e484dc87df7f5ca"));
318 tree.append("a=c", FileMode.REGULAR_FILE, ObjectId.fromString("06022365ddbd7fb126761319633bf73517770714"));
319 tree.append("a=d", FileMode.REGULAR_FILE, ObjectId.fromString("fa6414df3da87840700e9eeb7fc261dd77ccd5c2"));
320 ObjectId treeId = insertTree(tree);
321
322 FileTreeIterator iterator = new FileTreeIterator(db);
323 IndexDiff diff = new IndexDiff(db, treeId, iterator);
324 diff.diff();
325 assertEquals(0, diff.getChanged().size());
326 assertEquals(0, diff.getAdded().size());
327 assertEquals(0, diff.getRemoved().size());
328 assertEquals(0, diff.getMissing().size());
329 assertEquals(0, diff.getModified().size());
330 assertEquals(Collections.EMPTY_SET, diff.getUntrackedFolders());
331 }
332
333
334
335
336
337
338
339
340 @Test
341 public void testUnchangedComplex() throws IOException, GitAPIException {
342 Git git = new Git(db);
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 git.add().addFilepattern("a.b").addFilepattern("a.c")
351 .addFilepattern("a/b.b/b").addFilepattern("a/b")
352 .addFilepattern("a/c").addFilepattern("a=c")
353 .addFilepattern("a=d").call();
354
355
356
357 TreeFormatter bb = new TreeFormatter();
358 bb.append("b", FileMode.REGULAR_FILE, ObjectId.fromString("8d840bd4e2f3a48ff417c8e927d94996849933fd"));
359
360 TreeFormatter a = new TreeFormatter();
361 a.append("b", FileMode.REGULAR_FILE, ObjectId
362 .fromString("db89c972fc57862eae378f45b74aca228037d415"));
363 a.append("b.b", FileMode.TREE, insertTree(bb));
364 a.append("c", FileMode.REGULAR_FILE, ObjectId.fromString("52ad142a008aeb39694bafff8e8f1be75ed7f007"));
365
366 TreeFormatter tree = new TreeFormatter();
367 tree.append("a.b", FileMode.REGULAR_FILE, ObjectId.fromString("f6f28df96c2b40c951164286e08be7c38ec74851"));
368 tree.append("a.c", FileMode.REGULAR_FILE, ObjectId.fromString("6bc0e647512d2a0bef4f26111e484dc87df7f5ca"));
369 tree.append("a", FileMode.TREE, insertTree(a));
370 tree.append("a=c", FileMode.REGULAR_FILE, ObjectId.fromString("06022365ddbd7fb126761319633bf73517770714"));
371 tree.append("a=d", FileMode.REGULAR_FILE, ObjectId.fromString("fa6414df3da87840700e9eeb7fc261dd77ccd5c2"));
372 ObjectId treeId = insertTree(tree);
373
374 FileTreeIterator iterator = new FileTreeIterator(db);
375 IndexDiff diff = new IndexDiff(db, treeId, iterator);
376 diff.diff();
377 assertEquals(0, diff.getChanged().size());
378 assertEquals(0, diff.getAdded().size());
379 assertEquals(0, diff.getRemoved().size());
380 assertEquals(0, diff.getMissing().size());
381 assertEquals(0, diff.getModified().size());
382 assertEquals(Collections.EMPTY_SET, diff.getUntrackedFolders());
383 }
384
385 private ObjectId insertTree(TreeFormatter tree) throws IOException {
386 try (ObjectInserter oi = db.newObjectInserter()) {
387 ObjectId id = oi.insert(tree);
388 oi.flush();
389 return id;
390 }
391 }
392
393
394
395
396
397
398
399 @Test
400 public void testRemovedUntracked() throws Exception{
401 Git git = new Git(db);
402 String path = "file";
403 writeTrashFile(path, "content");
404 git.add().addFilepattern(path).call();
405 git.commit().setMessage("commit").call();
406 removeFromIndex(path);
407 FileTreeIterator iterator = new FileTreeIterator(db);
408 IndexDiff diff = new IndexDiff(db, Constants.HEAD, iterator);
409 diff.diff();
410 assertTrue(diff.getRemoved().contains(path));
411 assertTrue(diff.getUntracked().contains(path));
412 assertEquals(Collections.EMPTY_SET, diff.getUntrackedFolders());
413 }
414
415
416
417
418
419 @Test
420 public void testUntrackedFolders() throws Exception {
421 Git git = new Git(db);
422
423 IndexDiff diff = new IndexDiff(db, Constants.HEAD,
424 new FileTreeIterator(db));
425 diff.diff();
426 assertEquals(Collections.EMPTY_SET, diff.getUntrackedFolders());
427
428 writeTrashFile("readme", "");
429 writeTrashFile("src/com/A.java", "");
430 writeTrashFile("src/com/B.java", "");
431 writeTrashFile("src/org/A.java", "");
432 writeTrashFile("src/org/B.java", "");
433 writeTrashFile("target/com/A.java", "");
434 writeTrashFile("target/com/B.java", "");
435 writeTrashFile("target/org/A.java", "");
436 writeTrashFile("target/org/B.java", "");
437
438 git.add().addFilepattern("src").addFilepattern("readme").call();
439 git.commit().setMessage("initial").call();
440
441 diff = new IndexDiff(db, Constants.HEAD,
442 new FileTreeIterator(db));
443 diff.diff();
444 assertEquals(new HashSet<String>(Arrays.asList("target")),
445 diff.getUntrackedFolders());
446
447 writeTrashFile("src/tst/A.java", "");
448 writeTrashFile("src/tst/B.java", "");
449
450 diff = new IndexDiff(db, Constants.HEAD, new FileTreeIterator(db));
451 diff.diff();
452 assertEquals(new HashSet<String>(Arrays.asList("target", "src/tst")),
453 diff.getUntrackedFolders());
454
455 git.rm().addFilepattern("src/com/B.java").addFilepattern("src/org")
456 .call();
457 git.commit().setMessage("second").call();
458 writeTrashFile("src/org/C.java", "");
459
460 diff = new IndexDiff(db, Constants.HEAD, new FileTreeIterator(db));
461 diff.diff();
462 assertEquals(
463 new HashSet<String>(Arrays.asList("src/org", "src/tst",
464 "target")),
465 diff.getUntrackedFolders());
466 }
467
468
469
470
471
472
473 @Test
474 public void testUntrackedNotIgnoredFolders() throws Exception {
475 Git git = new Git(db);
476
477 IndexDiff diff = new IndexDiff(db, Constants.HEAD,
478 new FileTreeIterator(db));
479 diff.diff();
480 assertEquals(Collections.EMPTY_SET, diff.getUntrackedFolders());
481
482 writeTrashFile("readme", "");
483 writeTrashFile("sr/com/X.java", "");
484 writeTrashFile("src/com/A.java", "");
485 writeTrashFile("src/org/B.java", "");
486 writeTrashFile("srcs/org/Y.java", "");
487 writeTrashFile("target/com/A.java", "");
488 writeTrashFile("target/org/B.java", "");
489 writeTrashFile(".gitignore", "/target\n/sr");
490
491 git.add().addFilepattern("readme").addFilepattern(".gitignore")
492 .addFilepattern("srcs/").call();
493 git.commit().setMessage("initial").call();
494
495 diff = new IndexDiff(db, Constants.HEAD, new FileTreeIterator(db));
496 diff.diff();
497 assertEquals(new HashSet<String>(Arrays.asList("src")),
498 diff.getUntrackedFolders());
499
500 git.add().addFilepattern("src").call();
501 writeTrashFile("sr/com/X1.java", "");
502 writeTrashFile("src/tst/A.java", "");
503 writeTrashFile("src/tst/B.java", "");
504 writeTrashFile("srcs/com/Y1.java", "");
505 deleteTrashFile(".gitignore");
506
507 diff = new IndexDiff(db, Constants.HEAD, new FileTreeIterator(db));
508 diff.diff();
509 assertEquals(
510 new HashSet<String>(Arrays.asList("srcs/com", "sr", "src/tst",
511 "target")),
512 diff.getUntrackedFolders());
513 }
514
515 @Test
516 public void testAssumeUnchanged() throws Exception {
517 Git git = new Git(db);
518 String path = "file";
519 writeTrashFile(path, "content");
520 git.add().addFilepattern(path).call();
521 String path2 = "file2";
522 writeTrashFile(path2, "content");
523 String path3 = "file3";
524 writeTrashFile(path3, "some content");
525 git.add().addFilepattern(path2).addFilepattern(path3).call();
526 git.commit().setMessage("commit").call();
527 assumeUnchanged(path2);
528 assumeUnchanged(path3);
529 writeTrashFile(path, "more content");
530 deleteTrashFile(path3);
531
532 FileTreeIterator iterator = new FileTreeIterator(db);
533 IndexDiff diff = new IndexDiff(db, Constants.HEAD, iterator);
534 diff.diff();
535 assertEquals(2, diff.getAssumeUnchanged().size());
536 assertEquals(1, diff.getModified().size());
537 assertEquals(0, diff.getChanged().size());
538 assertTrue(diff.getAssumeUnchanged().contains("file2"));
539 assertTrue(diff.getAssumeUnchanged().contains("file3"));
540 assertTrue(diff.getModified().contains("file"));
541
542 git.add().addFilepattern(".").call();
543
544 iterator = new FileTreeIterator(db);
545 diff = new IndexDiff(db, Constants.HEAD, iterator);
546 diff.diff();
547 assertEquals(2, diff.getAssumeUnchanged().size());
548 assertEquals(0, diff.getModified().size());
549 assertEquals(1, diff.getChanged().size());
550 assertTrue(diff.getAssumeUnchanged().contains("file2"));
551 assertTrue(diff.getAssumeUnchanged().contains("file3"));
552 assertTrue(diff.getChanged().contains("file"));
553 assertEquals(Collections.EMPTY_SET, diff.getUntrackedFolders());
554 }
555
556 @Test
557 public void testStageState() throws IOException {
558 final int base = DirCacheEntry.STAGE_1;
559 final int ours = DirCacheEntry.STAGE_2;
560 final int theirs = DirCacheEntry.STAGE_3;
561 verifyStageState(StageState.BOTH_DELETED, base);
562 verifyStageState(StageState.DELETED_BY_THEM, ours, base);
563 verifyStageState(StageState.DELETED_BY_US, base, theirs);
564 verifyStageState(StageState.BOTH_MODIFIED, base, ours, theirs);
565 verifyStageState(StageState.ADDED_BY_US, ours);
566 verifyStageState(StageState.BOTH_ADDED, ours, theirs);
567 verifyStageState(StageState.ADDED_BY_THEM, theirs);
568
569 assertTrue(StageState.BOTH_DELETED.hasBase());
570 assertFalse(StageState.BOTH_DELETED.hasOurs());
571 assertFalse(StageState.BOTH_DELETED.hasTheirs());
572 assertFalse(StageState.BOTH_ADDED.hasBase());
573 assertTrue(StageState.BOTH_ADDED.hasOurs());
574 assertTrue(StageState.BOTH_ADDED.hasTheirs());
575 }
576
577 @Test
578 public void testStageState_mergeAndReset_bug() throws Exception {
579 Git git = new Git(db);
580
581 writeTrashFile("a", "content");
582 git.add().addFilepattern("a").call();
583 RevCommit initialCommit = git.commit().setMessage("initial commit")
584 .call();
585
586
587 final String branchName = Constants.R_HEADS + "branch";
588 createBranch(initialCommit, branchName);
589 checkoutBranch(branchName);
590 writeTrashFile("b", "second file content - branch");
591 git.add().addFilepattern("b").call();
592 RevCommit branchCommit = git.commit().setMessage("branch commit")
593 .call();
594
595
596 checkoutBranch(Constants.R_HEADS + Constants.MASTER);
597 writeTrashFile("b", "second file content - master");
598 git.add().addFilepattern("b").call();
599 git.commit().setMessage("master commit").call();
600
601
602 MergeResult result = git.merge().include(branchCommit).call();
603 assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());
604
605 FileTreeIterator iterator = new FileTreeIterator(db);
606 IndexDiff diff = new IndexDiff(db, Constants.HEAD, iterator);
607 diff.diff();
608
609 assertTrue(diff.getChanged().isEmpty());
610 assertTrue(diff.getAdded().isEmpty());
611 assertTrue(diff.getRemoved().isEmpty());
612 assertTrue(diff.getMissing().isEmpty());
613 assertTrue(diff.getModified().isEmpty());
614 assertEquals(1, diff.getConflicting().size());
615 assertTrue(diff.getConflicting().contains("b"));
616 assertEquals(StageState.BOTH_ADDED, diff.getConflictingStageStates()
617 .get("b"));
618 assertTrue(diff.getUntrackedFolders().isEmpty());
619
620
621 writeTrashFile("b", "second file content - master");
622
623
624 iterator = new FileTreeIterator(db);
625 diff = new IndexDiff(db, Constants.HEAD, iterator);
626 diff.diff();
627
628 assertTrue(diff.getChanged().isEmpty());
629 assertTrue(diff.getAdded().isEmpty());
630 assertTrue(diff.getRemoved().isEmpty());
631 assertTrue(diff.getMissing().isEmpty());
632 assertTrue(diff.getModified().isEmpty());
633 assertEquals(1, diff.getConflicting().size());
634 assertTrue(diff.getConflicting().contains("b"));
635 assertEquals(StageState.BOTH_ADDED, diff.getConflictingStageStates()
636 .get("b"));
637 assertTrue(diff.getUntrackedFolders().isEmpty());
638 }
639
640 @Test
641 public void testStageState_simulated_bug() throws Exception {
642 Git git = new Git(db);
643
644 writeTrashFile("a", "content");
645 git.add().addFilepattern("a").call();
646 RevCommit initialCommit = git.commit().setMessage("initial commit")
647 .call();
648
649
650 final String branchName = Constants.R_HEADS + "branch";
651 createBranch(initialCommit, branchName);
652 checkoutBranch(branchName);
653 writeTrashFile("b", "second file content - branch");
654 git.add().addFilepattern("b").call();
655 git.commit().setMessage("branch commit")
656 .call();
657
658
659 checkoutBranch(Constants.R_HEADS + Constants.MASTER);
660 writeTrashFile("b", "second file content - master");
661 git.add().addFilepattern("b").call();
662 git.commit().setMessage("master commit").call();
663
664
665 DirCacheBuilder builder = db.lockDirCache().builder();
666 DirCacheEntry entry = createEntry("a", FileMode.REGULAR_FILE, 0,
667 "content");
668 builder.add(entry);
669 entry = createEntry("b", FileMode.REGULAR_FILE, 2,
670 "second file content - master");
671 builder.add(entry);
672 entry = createEntry("b", FileMode.REGULAR_FILE, 3,
673 "second file content - branch");
674 builder.add(entry);
675 builder.commit();
676
677 FileTreeIterator iterator = new FileTreeIterator(db);
678 IndexDiff diff = new IndexDiff(db, Constants.HEAD, iterator);
679 diff.diff();
680
681 assertTrue(diff.getChanged().isEmpty());
682 assertTrue(diff.getAdded().isEmpty());
683 assertTrue(diff.getRemoved().isEmpty());
684 assertTrue(diff.getMissing().isEmpty());
685 assertTrue(diff.getModified().isEmpty());
686 assertEquals(1, diff.getConflicting().size());
687 assertTrue(diff.getConflicting().contains("b"));
688 assertEquals(StageState.BOTH_ADDED, diff.getConflictingStageStates()
689 .get("b"));
690 assertTrue(diff.getUntrackedFolders().isEmpty());
691 }
692
693 @Test
694 public void testAutoCRLFInput() throws Exception {
695 Git git = new Git(db);
696 FileBasedConfig config = db.getConfig();
697
698
699 config.setEnum(ConfigConstants.CONFIG_CORE_SECTION, null,
700 ConfigConstants.CONFIG_KEY_AUTOCRLF, AutoCRLF.FALSE);
701 config.save();
702
703
704 writeTrashFile("crlf.txt", "this\r\ncontains\r\ncrlf\r\n");
705 git.add().addFilepattern("crlf.txt").call();
706 git.commit().setMessage("Add crlf.txt").call();
707
708
709 config.setEnum(ConfigConstants.CONFIG_CORE_SECTION, null,
710 ConfigConstants.CONFIG_KEY_AUTOCRLF, AutoCRLF.INPUT);
711 config.save();
712
713 FileTreeIterator iterator = new FileTreeIterator(db);
714 IndexDiff diff = new IndexDiff(db, Constants.HEAD, iterator);
715 diff.diff();
716
717 assertTrue(
718 "Expected no modified files, but there were: "
719 + diff.getModified(), diff.getModified().isEmpty());
720 }
721
722 private void verifyStageState(StageState expected, int... stages)
723 throws IOException {
724 DirCacheBuilder builder = db.lockDirCache().builder();
725 for (int stage : stages) {
726 DirCacheEntry entry = createEntry("a", FileMode.REGULAR_FILE,
727 stage, "content");
728 builder.add(entry);
729 }
730 builder.commit();
731
732 IndexDiff diff = new IndexDiff(db, Constants.HEAD,
733 new FileTreeIterator(db));
734 diff.diff();
735
736 assertEquals(
737 "Conflict for entries in stages " + Arrays.toString(stages),
738 expected, diff.getConflictingStageStates().get("a"));
739 }
740
741 private void removeFromIndex(String path) throws IOException {
742 final DirCache dirc = db.lockDirCache();
743 final DirCacheEditor edit = dirc.editor();
744 edit.add(new DirCacheEditor.DeletePath(path));
745 if (!edit.commit())
746 throw new IOException("could not commit");
747 }
748
749 private void assumeUnchanged(String path) throws IOException {
750 final DirCache dirc = db.lockDirCache();
751 final DirCacheEntry ent = dirc.getEntry(path);
752 if (ent != null)
753 ent.setAssumeValid(true);
754 dirc.write();
755 if (!dirc.commit())
756 throw new IOException("could not commit");
757 }
758
759 }