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 package org.eclipse.jgit.api;
44
45 import static org.junit.Assert.assertEquals;
46 import static org.junit.Assert.assertFalse;
47 import static org.junit.Assert.assertNotNull;
48 import static org.junit.Assert.assertTrue;
49 import static org.junit.Assert.fail;
50
51 import java.io.File;
52 import java.text.MessageFormat;
53
54 import org.eclipse.jgit.api.errors.InvalidRefNameException;
55 import org.eclipse.jgit.api.errors.JGitInternalException;
56 import org.eclipse.jgit.api.errors.NoHeadException;
57 import org.eclipse.jgit.api.errors.StashApplyFailureException;
58 import org.eclipse.jgit.events.ChangeRecorder;
59 import org.eclipse.jgit.events.ListenerHandle;
60 import org.eclipse.jgit.internal.JGitText;
61 import org.eclipse.jgit.junit.RepositoryTestCase;
62 import org.eclipse.jgit.lib.ObjectId;
63 import org.eclipse.jgit.lib.Repository;
64 import org.eclipse.jgit.revwalk.RevCommit;
65 import org.eclipse.jgit.util.FileUtils;
66 import org.junit.After;
67 import org.junit.Before;
68 import org.junit.Test;
69
70
71
72
73 public class StashApplyCommandTest extends RepositoryTestCase {
74
75 private static final String PATH = "file.txt";
76
77 private RevCommit head;
78
79 private Git git;
80
81 private File committedFile;
82
83 private ChangeRecorder recorder;
84
85 private ListenerHandle handle;
86
87 @Override
88 @Before
89 public void setUp() throws Exception {
90 super.setUp();
91 git = Git.wrap(db);
92 recorder = new ChangeRecorder();
93 handle = db.getListenerList().addWorkingTreeModifiedListener(recorder);
94 committedFile = writeTrashFile(PATH, "content");
95 git.add().addFilepattern(PATH).call();
96 head = git.commit().setMessage("add file").call();
97 assertNotNull(head);
98 recorder.assertNoEvent();
99 }
100
101 @Override
102 @After
103 public void tearDown() throws Exception {
104 if (handle != null) {
105 handle.remove();
106 }
107 super.tearDown();
108 }
109
110 @Test
111 public void workingDirectoryDelete() throws Exception {
112 deleteTrashFile(PATH);
113 assertFalse(committedFile.exists());
114 RevCommit stashed = git.stashCreate().call();
115 assertNotNull(stashed);
116 assertEquals("content", read(committedFile));
117 recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY);
118
119 ObjectId unstashed = git.stashApply().call();
120 assertEquals(stashed, unstashed);
121 assertFalse(committedFile.exists());
122 recorder.assertEvent(ChangeRecorder.EMPTY, new String[] { PATH });
123
124 Status status = git.status().call();
125 assertTrue(status.getAdded().isEmpty());
126 assertTrue(status.getChanged().isEmpty());
127 assertTrue(status.getConflicting().isEmpty());
128 assertTrue(status.getModified().isEmpty());
129 assertTrue(status.getUntracked().isEmpty());
130 assertTrue(status.getRemoved().isEmpty());
131
132 assertEquals(1, status.getMissing().size());
133 assertTrue(status.getMissing().contains(PATH));
134 }
135
136 @Test
137 public void indexAdd() throws Exception {
138 String addedPath = "file2.txt";
139 File addedFile = writeTrashFile(addedPath, "content2");
140 git.add().addFilepattern(addedPath).call();
141
142 RevCommit stashed = git.stashCreate().call();
143 assertNotNull(stashed);
144 assertFalse(addedFile.exists());
145 recorder.assertEvent(ChangeRecorder.EMPTY, new String[] { addedPath });
146
147 ObjectId unstashed = git.stashApply().call();
148 assertEquals(stashed, unstashed);
149 assertTrue(addedFile.exists());
150 assertEquals("content2", read(addedFile));
151 recorder.assertEvent(new String[] { addedPath }, ChangeRecorder.EMPTY);
152
153 Status status = git.status().call();
154 assertTrue(status.getChanged().isEmpty());
155 assertTrue(status.getConflicting().isEmpty());
156 assertTrue(status.getMissing().isEmpty());
157 assertTrue(status.getModified().isEmpty());
158 assertTrue(status.getRemoved().isEmpty());
159 assertTrue(status.getUntracked().isEmpty());
160
161 assertEquals(1, status.getAdded().size());
162 assertTrue(status.getAdded().contains(addedPath));
163 }
164
165 @Test
166 public void indexDelete() throws Exception {
167 git.rm().addFilepattern("file.txt").call();
168 recorder.assertEvent(ChangeRecorder.EMPTY, new String[] { "file.txt" });
169
170 RevCommit stashed = git.stashCreate().call();
171 assertNotNull(stashed);
172 assertEquals("content", read(committedFile));
173 recorder.assertEvent(new String[] { "file.txt" }, ChangeRecorder.EMPTY);
174
175 ObjectId unstashed = git.stashApply().call();
176 assertEquals(stashed, unstashed);
177 assertFalse(committedFile.exists());
178 recorder.assertEvent(ChangeRecorder.EMPTY, new String[] { "file.txt" });
179
180 Status status = git.status().call();
181 assertTrue(status.getAdded().isEmpty());
182 assertTrue(status.getChanged().isEmpty());
183 assertTrue(status.getConflicting().isEmpty());
184 assertTrue(status.getModified().isEmpty());
185 assertTrue(status.getMissing().isEmpty());
186 assertTrue(status.getUntracked().isEmpty());
187
188 assertEquals(1, status.getRemoved().size());
189 assertTrue(status.getRemoved().contains(PATH));
190 }
191
192 @Test
193 public void workingDirectoryModify() throws Exception {
194 writeTrashFile("file.txt", "content2");
195
196 RevCommit stashed = git.stashCreate().call();
197 assertNotNull(stashed);
198 assertEquals("content", read(committedFile));
199 recorder.assertEvent(new String[] { "file.txt" }, ChangeRecorder.EMPTY);
200
201 ObjectId unstashed = git.stashApply().call();
202 assertEquals(stashed, unstashed);
203 assertEquals("content2", read(committedFile));
204 recorder.assertEvent(new String[] { "file.txt" }, ChangeRecorder.EMPTY);
205
206 Status status = git.status().call();
207 assertTrue(status.getAdded().isEmpty());
208 assertTrue(status.getChanged().isEmpty());
209 assertTrue(status.getConflicting().isEmpty());
210 assertTrue(status.getMissing().isEmpty());
211 assertTrue(status.getRemoved().isEmpty());
212 assertTrue(status.getUntracked().isEmpty());
213
214 assertEquals(1, status.getModified().size());
215 assertTrue(status.getModified().contains(PATH));
216 }
217
218 @Test
219 public void workingDirectoryModifyInSubfolder() throws Exception {
220 String path = "d1/d2/f.txt";
221 File subfolderFile = writeTrashFile(path, "content");
222 git.add().addFilepattern(path).call();
223 head = git.commit().setMessage("add file").call();
224 recorder.assertNoEvent();
225
226 writeTrashFile(path, "content2");
227
228 RevCommit stashed = git.stashCreate().call();
229 assertNotNull(stashed);
230 assertEquals("content", read(subfolderFile));
231 recorder.assertEvent(new String[] { "d1/d2/f.txt" },
232 ChangeRecorder.EMPTY);
233
234 ObjectId unstashed = git.stashApply().call();
235 assertEquals(stashed, unstashed);
236 assertEquals("content2", read(subfolderFile));
237 recorder.assertEvent(new String[] { "d1/d2/f.txt" },
238 ChangeRecorder.EMPTY);
239
240 Status status = git.status().call();
241 assertTrue(status.getAdded().isEmpty());
242 assertTrue(status.getChanged().isEmpty());
243 assertTrue(status.getConflicting().isEmpty());
244 assertTrue(status.getMissing().isEmpty());
245 assertTrue(status.getRemoved().isEmpty());
246 assertTrue(status.getUntracked().isEmpty());
247
248 assertEquals(1, status.getModified().size());
249 assertTrue(status.getModified().contains(path));
250 }
251
252 @Test
253 public void workingDirectoryModifyIndexChanged() throws Exception {
254 writeTrashFile("file.txt", "content2");
255 git.add().addFilepattern("file.txt").call();
256 writeTrashFile("file.txt", "content3");
257
258 RevCommit stashed = git.stashCreate().call();
259 assertNotNull(stashed);
260 assertEquals("content", read(committedFile));
261 recorder.assertEvent(new String[] { "file.txt" }, ChangeRecorder.EMPTY);
262
263 ObjectId unstashed = git.stashApply().call();
264 assertEquals(stashed, unstashed);
265 assertEquals("content3", read(committedFile));
266 recorder.assertEvent(new String[] { "file.txt" }, ChangeRecorder.EMPTY);
267
268 Status status = git.status().call();
269 assertTrue(status.getAdded().isEmpty());
270 assertTrue(status.getConflicting().isEmpty());
271 assertTrue(status.getMissing().isEmpty());
272 assertTrue(status.getRemoved().isEmpty());
273 assertTrue(status.getUntracked().isEmpty());
274
275 assertEquals(1, status.getChanged().size());
276 assertTrue(status.getChanged().contains(PATH));
277 assertEquals(1, status.getModified().size());
278 assertTrue(status.getModified().contains(PATH));
279 }
280
281 @Test
282 public void workingDirectoryCleanIndexModify() throws Exception {
283 writeTrashFile("file.txt", "content2");
284 git.add().addFilepattern("file.txt").call();
285 writeTrashFile("file.txt", "content");
286
287 RevCommit stashed = git.stashCreate().call();
288 assertNotNull(stashed);
289 assertEquals("content", read(committedFile));
290 recorder.assertEvent(new String[] { "file.txt" }, ChangeRecorder.EMPTY);
291
292 ObjectId unstashed = git.stashApply().call();
293 assertEquals(stashed, unstashed);
294 assertEquals("content2", read(committedFile));
295 recorder.assertEvent(new String[] { "file.txt" }, ChangeRecorder.EMPTY);
296
297 Status status = git.status().call();
298 assertTrue(status.getAdded().isEmpty());
299 assertTrue(status.getConflicting().isEmpty());
300 assertTrue(status.getMissing().isEmpty());
301 assertTrue(status.getModified().isEmpty());
302 assertTrue(status.getRemoved().isEmpty());
303 assertTrue(status.getUntracked().isEmpty());
304
305 assertEquals(1, status.getChanged().size());
306 assertTrue(status.getChanged().contains(PATH));
307 }
308
309 @Test
310 public void workingDirectoryDeleteIndexAdd() throws Exception {
311 String path = "file2.txt";
312 File added = writeTrashFile(path, "content2");
313 assertTrue(added.exists());
314 git.add().addFilepattern(path).call();
315 FileUtils.delete(added);
316 assertFalse(added.exists());
317
318 RevCommit stashed = git.stashCreate().call();
319 assertNotNull(stashed);
320 assertFalse(added.exists());
321 recorder.assertNoEvent();
322
323 ObjectId unstashed = git.stashApply().call();
324 assertEquals(stashed, unstashed);
325 assertEquals("content2", read(added));
326 recorder.assertEvent(new String[] { path }, ChangeRecorder.EMPTY);
327
328 Status status = git.status().call();
329 assertTrue(status.getChanged().isEmpty());
330 assertTrue(status.getConflicting().isEmpty());
331 assertTrue(status.getMissing().isEmpty());
332 assertTrue(status.getModified().isEmpty());
333 assertTrue(status.getRemoved().isEmpty());
334 assertTrue(status.getUntracked().isEmpty());
335
336 assertEquals(1, status.getAdded().size());
337 assertTrue(status.getAdded().contains(path));
338 }
339
340 @Test
341 public void workingDirectoryDeleteIndexEdit() throws Exception {
342 writeTrashFile(PATH, "content2");
343 git.add().addFilepattern(PATH).call();
344 FileUtils.delete(committedFile);
345 assertFalse(committedFile.exists());
346
347 RevCommit stashed = git.stashCreate().call();
348 assertNotNull(stashed);
349 assertEquals("content", read(committedFile));
350 recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY);
351
352 ObjectId unstashed = git.stashApply().call();
353 assertEquals(stashed, unstashed);
354 assertFalse(committedFile.exists());
355 recorder.assertEvent(ChangeRecorder.EMPTY, new String[] { PATH });
356
357 Status status = git.status().call();
358 assertTrue(status.getAdded().isEmpty());
359 assertEquals(1, status.getChanged().size());
360 assertTrue(status.getChanged().contains(PATH));
361 assertTrue(status.getConflicting().isEmpty());
362 assertEquals(1, status.getMissing().size());
363 assertTrue(status.getMissing().contains(PATH));
364 assertTrue(status.getModified().isEmpty());
365 assertTrue(status.getUntracked().isEmpty());
366
367 assertTrue(status.getRemoved().isEmpty());
368 }
369
370 @Test
371 public void multipleEdits() throws Exception {
372 String addedPath = "file2.txt";
373 git.rm().addFilepattern(PATH).call();
374 File addedFile = writeTrashFile(addedPath, "content2");
375 git.add().addFilepattern(addedPath).call();
376
377 RevCommit stashed = git.stashCreate().call();
378 assertNotNull(stashed);
379 assertTrue(committedFile.exists());
380 assertFalse(addedFile.exists());
381 recorder.assertEvent(new String[] { PATH },
382 new String[] { "file2.txt" });
383
384 ObjectId unstashed = git.stashApply().call();
385 assertEquals(stashed, unstashed);
386 recorder.assertEvent(new String[] { "file2.txt" },
387 new String[] { PATH });
388
389 Status status = git.status().call();
390 assertTrue(status.getChanged().isEmpty());
391 assertTrue(status.getConflicting().isEmpty());
392 assertTrue(status.getMissing().isEmpty());
393 assertTrue(status.getModified().isEmpty());
394 assertTrue(status.getUntracked().isEmpty());
395
396 assertEquals(1, status.getRemoved().size());
397 assertTrue(status.getRemoved().contains(PATH));
398 assertEquals(1, status.getAdded().size());
399 assertTrue(status.getAdded().contains(addedPath));
400 }
401
402 @Test
403 public void workingDirectoryContentConflict() throws Exception {
404 writeTrashFile(PATH, "content2");
405
406 RevCommit stashed = git.stashCreate().call();
407 assertNotNull(stashed);
408 assertEquals("content", read(committedFile));
409 assertTrue(git.status().call().isClean());
410 recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY);
411
412 writeTrashFile(PATH, "content3");
413
414 try {
415 git.stashApply().call();
416 fail("Exception not thrown");
417 } catch (StashApplyFailureException e) {
418
419 }
420 assertEquals("content3", read(PATH));
421 recorder.assertNoEvent();
422 }
423
424 @Test
425 public void stashedContentMerge() throws Exception {
426 writeTrashFile(PATH, "content\nmore content\n");
427 git.add().addFilepattern(PATH).call();
428 git.commit().setMessage("more content").call();
429
430 writeTrashFile(PATH, "content\nhead change\nmore content\n");
431 git.add().addFilepattern(PATH).call();
432 git.commit().setMessage("even content").call();
433
434 writeTrashFile(PATH, "content\nstashed change\nmore content\n");
435
436 RevCommit stashed = git.stashCreate().call();
437 assertNotNull(stashed);
438 assertEquals("content\nhead change\nmore content\n",
439 read(committedFile));
440 assertTrue(git.status().call().isClean());
441 recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY);
442
443 writeTrashFile(PATH, "content\nmore content\ncommitted change\n");
444 git.add().addFilepattern(PATH).call();
445 git.commit().setMessage("committed change").call();
446 recorder.assertNoEvent();
447
448 try {
449 git.stashApply().call();
450 fail("Expected conflict");
451 } catch (StashApplyFailureException e) {
452
453 }
454 recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY);
455 Status status = new StatusCommand(db).call();
456 assertEquals(1, status.getConflicting().size());
457 assertEquals(
458 "content\n<<<<<<< HEAD\n=======\nstashed change\n>>>>>>> stash\nmore content\ncommitted change\n",
459 read(PATH));
460 }
461
462 @Test
463 public void stashedApplyOnOtherBranch() throws Exception {
464 writeTrashFile(PATH, "content\nmore content\n");
465 git.add().addFilepattern(PATH).call();
466 git.commit().setMessage("more content").call();
467 String path2 = "file2.txt";
468 File file2 = writeTrashFile(path2, "content\nmore content\n");
469 git.add().addFilepattern(PATH).call();
470 git.add().addFilepattern(path2).call();
471 git.commit().setMessage("even content").call();
472
473 String otherBranch = "otherBranch";
474 git.branchCreate().setName(otherBranch).call();
475
476 writeTrashFile(PATH, "master content");
477 git.add().addFilepattern(PATH).call();
478 git.commit().setMessage("even content").call();
479 recorder.assertNoEvent();
480
481 git.checkout().setName(otherBranch).call();
482 recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY);
483
484 writeTrashFile(PATH, "otherBranch content");
485 git.add().addFilepattern(PATH).call();
486 git.commit().setMessage("even more content").call();
487 recorder.assertNoEvent();
488
489 writeTrashFile(path2, "content\nstashed change\nmore content\n");
490
491 RevCommit stashed = git.stashCreate().call();
492
493 assertNotNull(stashed);
494 assertEquals("content\nmore content\n", read(file2));
495 assertEquals("otherBranch content",
496 read(committedFile));
497 assertTrue(git.status().call().isClean());
498 recorder.assertEvent(new String[] { path2 }, ChangeRecorder.EMPTY);
499
500 git.checkout().setName("master").call();
501 recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY);
502 git.stashApply().call();
503 assertEquals("content\nstashed change\nmore content\n", read(file2));
504 assertEquals("master content",
505 read(committedFile));
506 recorder.assertEvent(new String[] { path2 }, ChangeRecorder.EMPTY);
507 }
508
509 @Test
510 public void stashedApplyOnOtherBranchWithStagedChange() throws Exception {
511 writeTrashFile(PATH, "content\nmore content\n");
512 git.add().addFilepattern(PATH).call();
513 git.commit().setMessage("more content").call();
514 String path2 = "file2.txt";
515 File file2 = writeTrashFile(path2, "content\nmore content\n");
516 git.add().addFilepattern(PATH).call();
517 git.add().addFilepattern(path2).call();
518 git.commit().setMessage("even content").call();
519
520 String otherBranch = "otherBranch";
521 git.branchCreate().setName(otherBranch).call();
522
523 writeTrashFile(PATH, "master content");
524 git.add().addFilepattern(PATH).call();
525 git.commit().setMessage("even content").call();
526 recorder.assertNoEvent();
527
528 git.checkout().setName(otherBranch).call();
529 recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY);
530
531 writeTrashFile(PATH, "otherBranch content");
532 git.add().addFilepattern(PATH).call();
533 git.commit().setMessage("even more content").call();
534 recorder.assertNoEvent();
535
536 writeTrashFile(path2,
537 "content\nstashed change in index\nmore content\n");
538 git.add().addFilepattern(path2).call();
539 writeTrashFile(path2, "content\nstashed change\nmore content\n");
540
541 RevCommit stashed = git.stashCreate().call();
542
543 assertNotNull(stashed);
544 assertEquals("content\nmore content\n", read(file2));
545 assertEquals("otherBranch content", read(committedFile));
546 assertTrue(git.status().call().isClean());
547 recorder.assertEvent(new String[] { path2 }, ChangeRecorder.EMPTY);
548
549 git.checkout().setName("master").call();
550 recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY);
551 git.stashApply().call();
552 assertEquals("content\nstashed change\nmore content\n", read(file2));
553 assertEquals(
554 "[file.txt, mode:100644, content:master content]"
555 + "[file2.txt, mode:100644, content:content\nstashed change in index\nmore content\n]",
556 indexState(CONTENT));
557 assertEquals("master content", read(committedFile));
558 recorder.assertEvent(new String[] { path2 }, ChangeRecorder.EMPTY);
559 }
560
561 @Test
562 public void workingDirectoryContentMerge() throws Exception {
563 writeTrashFile(PATH, "content\nmore content\n");
564 git.add().addFilepattern(PATH).call();
565 git.commit().setMessage("more content").call();
566 recorder.assertNoEvent();
567
568 writeTrashFile(PATH, "content\nstashed change\nmore content\n");
569
570 RevCommit stashed = git.stashCreate().call();
571 assertNotNull(stashed);
572 assertEquals("content\nmore content\n", read(committedFile));
573 assertTrue(git.status().call().isClean());
574 recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY);
575
576 writeTrashFile(PATH, "content\nmore content\ncommitted change\n");
577 git.add().addFilepattern(PATH).call();
578 git.commit().setMessage("committed change").call();
579 recorder.assertNoEvent();
580
581 git.stashApply().call();
582 assertEquals(
583 "content\nstashed change\nmore content\ncommitted change\n",
584 read(committedFile));
585 recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY);
586 }
587
588 @Test
589 public void indexContentConflict() throws Exception {
590 writeTrashFile(PATH, "content2");
591
592 RevCommit stashed = git.stashCreate().call();
593 assertNotNull(stashed);
594 assertEquals("content", read(committedFile));
595 assertTrue(git.status().call().isClean());
596 recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY);
597
598 writeTrashFile(PATH, "content3");
599 git.add().addFilepattern(PATH).call();
600 writeTrashFile(PATH, "content2");
601
602 try {
603 git.stashApply().call();
604 fail("Exception not thrown");
605 } catch (StashApplyFailureException e) {
606
607 }
608 recorder.assertNoEvent();
609 assertEquals("content2", read(PATH));
610 }
611
612 @Test
613 public void workingDirectoryEditPreCommit() throws Exception {
614 writeTrashFile(PATH, "content2");
615
616 RevCommit stashed = git.stashCreate().call();
617 assertNotNull(stashed);
618 assertEquals("content", read(committedFile));
619 assertTrue(git.status().call().isClean());
620 recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY);
621
622 String path2 = "file2.txt";
623 writeTrashFile(path2, "content3");
624 git.add().addFilepattern(path2).call();
625 assertNotNull(git.commit().setMessage("adding file").call());
626
627 ObjectId unstashed = git.stashApply().call();
628 assertEquals(stashed, unstashed);
629 recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY);
630
631 Status status = git.status().call();
632 assertTrue(status.getAdded().isEmpty());
633 assertTrue(status.getChanged().isEmpty());
634 assertTrue(status.getConflicting().isEmpty());
635 assertTrue(status.getMissing().isEmpty());
636 assertTrue(status.getRemoved().isEmpty());
637 assertTrue(status.getUntracked().isEmpty());
638
639 assertEquals(1, status.getModified().size());
640 assertTrue(status.getModified().contains(PATH));
641 }
642
643 @Test
644 public void stashChangeInANewSubdirectory() throws Exception {
645 String subdir = "subdir";
646 String fname = "file2.txt";
647 String path = subdir + "/" + fname;
648 String otherBranch = "otherbranch";
649
650 writeTrashFile(subdir, fname, "content2");
651
652 git.add().addFilepattern(path).call();
653 RevCommit stashed = git.stashCreate().call();
654 assertNotNull(stashed);
655 assertTrue(git.status().call().isClean());
656 recorder.assertEvent(ChangeRecorder.EMPTY,
657 new String[] { subdir, path });
658
659 git.branchCreate().setName(otherBranch).call();
660 git.checkout().setName(otherBranch).call();
661
662 ObjectId unstashed = git.stashApply().call();
663 assertEquals(stashed, unstashed);
664 recorder.assertEvent(new String[] { path }, ChangeRecorder.EMPTY);
665
666 Status status = git.status().call();
667 assertTrue(status.getChanged().isEmpty());
668 assertTrue(status.getConflicting().isEmpty());
669 assertTrue(status.getMissing().isEmpty());
670 assertTrue(status.getRemoved().isEmpty());
671 assertTrue(status.getModified().isEmpty());
672 assertTrue(status.getUntracked().isEmpty());
673
674 assertEquals(1, status.getAdded().size());
675 assertTrue(status.getAdded().contains(path));
676 }
677
678 @Test
679 public void unstashNonStashCommit() throws Exception {
680 try {
681 git.stashApply().setStashRef(head.name()).call();
682 fail("Exception not thrown");
683 } catch (JGitInternalException e) {
684 assertEquals(MessageFormat.format(
685 JGitText.get().stashCommitIncorrectNumberOfParents,
686 head.name(), "0"),
687 e.getMessage());
688 }
689 }
690
691 @Test
692 public void unstashNoHead() throws Exception {
693 Repository repo = createWorkRepository();
694 try {
695 Git.wrap(repo).stashApply().call();
696 fail("Exception not thrown");
697 } catch (NoHeadException e) {
698 assertNotNull(e.getMessage());
699 }
700 }
701
702 @Test
703 public void noStashedCommits() throws Exception {
704 try {
705 git.stashApply().call();
706 fail("Exception not thrown");
707 } catch (InvalidRefNameException e) {
708 assertNotNull(e.getMessage());
709 }
710 }
711
712 @Test
713 public void testApplyStashWithDeletedFile() throws Exception {
714 File file = writeTrashFile("file", "content");
715 git.add().addFilepattern("file").call();
716 git.commit().setMessage("x").call();
717 file.delete();
718 git.rm().addFilepattern("file").call();
719 recorder.assertNoEvent();
720 git.stashCreate().call();
721 recorder.assertEvent(new String[] { "file" }, ChangeRecorder.EMPTY);
722 file.delete();
723
724 git.stashApply().setStashRef("stash@{0}").call();
725
726 assertFalse(file.exists());
727 recorder.assertEvent(ChangeRecorder.EMPTY, new String[] { "file" });
728 }
729
730 @Test
731 public void untrackedFileNotIncluded() throws Exception {
732 String untrackedPath = "untracked.txt";
733 File untrackedFile = writeTrashFile(untrackedPath, "content");
734
735 writeTrashFile(PATH, "content2");
736 git.add().addFilepattern(PATH).call();
737 git.stashCreate().call();
738 assertTrue(untrackedFile.exists());
739 recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY);
740
741 git.stashApply().setStashRef("stash@{0}").call();
742 assertTrue(untrackedFile.exists());
743 recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY);
744
745 Status status = git.status().call();
746 assertEquals(1, status.getUntracked().size());
747 assertTrue(status.getUntracked().contains(untrackedPath));
748 assertEquals(1, status.getChanged().size());
749 assertTrue(status.getChanged().contains(PATH));
750 assertTrue(status.getAdded().isEmpty());
751 assertTrue(status.getConflicting().isEmpty());
752 assertTrue(status.getMissing().isEmpty());
753 assertTrue(status.getRemoved().isEmpty());
754 assertTrue(status.getModified().isEmpty());
755 }
756
757 @Test
758 public void untrackedFileIncluded() throws Exception {
759 String path = "a/b/untracked.txt";
760 File untrackedFile = writeTrashFile(path, "content");
761 RevCommit stashedCommit = git.stashCreate().setIncludeUntracked(true)
762 .call();
763 assertNotNull(stashedCommit);
764 assertFalse(untrackedFile.exists());
765 recorder.assertEvent(ChangeRecorder.EMPTY, new String[] { path });
766
767 deleteTrashFile("a/b");
768
769 git.stashApply().setStashRef("stash@{0}").call();
770 assertTrue(untrackedFile.exists());
771 assertEquals("content", read(path));
772 recorder.assertEvent(new String[] { path }, ChangeRecorder.EMPTY);
773
774 Status status = git.status().call();
775 assertEquals(1, status.getUntracked().size());
776 assertTrue(status.getAdded().isEmpty());
777 assertTrue(status.getChanged().isEmpty());
778 assertTrue(status.getConflicting().isEmpty());
779 assertTrue(status.getMissing().isEmpty());
780 assertTrue(status.getRemoved().isEmpty());
781 assertTrue(status.getModified().isEmpty());
782 assertTrue(status.getUntracked().contains(path));
783 }
784
785 @Test
786 public void untrackedFileConflictsWithCommit() throws Exception {
787 String path = "untracked.txt";
788 writeTrashFile(path, "untracked");
789 git.stashCreate().setIncludeUntracked(true).call();
790 recorder.assertEvent(ChangeRecorder.EMPTY, new String[] { path });
791
792 writeTrashFile(path, "committed");
793 head = git.commit().setMessage("add file").call();
794 git.add().addFilepattern(path).call();
795 git.commit().setMessage("conflicting commit").call();
796
797 try {
798 git.stashApply().setStashRef("stash@{0}").call();
799 fail("StashApplyFailureException should be thrown.");
800 } catch (StashApplyFailureException e) {
801 assertEquals(e.getMessage(), JGitText.get().stashApplyConflict);
802 }
803 assertEquals("committed", read(path));
804 recorder.assertNoEvent();
805 }
806
807 @Test
808 public void untrackedFileConflictsWithWorkingDirectory()
809 throws Exception {
810 String path = "untracked.txt";
811 writeTrashFile(path, "untracked");
812 git.stashCreate().setIncludeUntracked(true).call();
813 recorder.assertEvent(ChangeRecorder.EMPTY, new String[] { path });
814
815 writeTrashFile(path, "working-directory");
816 try {
817 git.stashApply().setStashRef("stash@{0}").call();
818 fail("StashApplyFailureException should be thrown.");
819 } catch (StashApplyFailureException e) {
820 assertEquals(e.getMessage(), JGitText.get().stashApplyConflict);
821 }
822 assertEquals("working-directory", read(path));
823 recorder.assertNoEvent();
824 }
825
826 @Test
827 public void untrackedAndTrackedChanges() throws Exception {
828 writeTrashFile(PATH, "changed");
829 String path = "untracked.txt";
830 writeTrashFile(path, "untracked");
831 git.stashCreate().setIncludeUntracked(true).call();
832 assertTrue(PATH + " should exist", check(PATH));
833 assertEquals(PATH + " should have been reset", "content", read(PATH));
834 assertFalse(path + " should not exist", check(path));
835 recorder.assertEvent(new String[] { PATH }, new String[] { path });
836 git.stashApply().setStashRef("stash@{0}").call();
837 assertTrue(PATH + " should exist", check(PATH));
838 assertEquals(PATH + " should have new content", "changed", read(PATH));
839 assertTrue(path + " should exist", check(path));
840 assertEquals(path + " should have new content", "untracked",
841 read(path));
842 recorder.assertEvent(new String[] { PATH, path }, ChangeRecorder.EMPTY);
843 }
844 }