Merge branch 'jk/test-chain-lint'
[git.git] / t / t3903-stash.sh
blob0746eeeff70c29c91accacdfa1efa4bc2e612715
1 #!/bin/sh
3 # Copyright (c) 2007 Johannes E Schindelin
6 test_description='Test git stash'
8 . ./test-lib.sh
10 test_expect_success 'stash some dirty working directory' '
11 echo 1 > file &&
12 git add file &&
13 echo unrelated >other-file &&
14 git add other-file &&
15 test_tick &&
16 git commit -m initial &&
17 echo 2 > file &&
18 git add file &&
19 echo 3 > file &&
20 test_tick &&
21 git stash &&
22 git diff-files --quiet &&
23 git diff-index --cached --quiet HEAD
26 cat > expect << EOF
27 diff --git a/file b/file
28 index 0cfbf08..00750ed 100644
29 --- a/file
30 +++ b/file
31 @@ -1 +1 @@
34 EOF
36 test_expect_success 'parents of stash' '
37 test $(git rev-parse stash^) = $(git rev-parse HEAD) &&
38 git diff stash^2..stash > output &&
39 test_cmp output expect
42 test_expect_success 'applying bogus stash does nothing' '
43 test_must_fail git stash apply stash@{1} &&
44 echo 1 >expect &&
45 test_cmp expect file
48 test_expect_success 'apply requires a clean index' '
49 test_when_finished "git reset --hard" &&
50 echo changed >other-file &&
51 git add other-file &&
52 test_must_fail git stash apply
55 test_expect_success 'apply does not need clean working directory' '
56 echo 4 >other-file &&
57 git stash apply &&
58 echo 3 >expect &&
59 test_cmp expect file
62 test_expect_success 'apply does not clobber working directory changes' '
63 git reset --hard &&
64 echo 4 >file &&
65 test_must_fail git stash apply &&
66 echo 4 >expect &&
67 test_cmp expect file
70 test_expect_success 'apply stashed changes' '
71 git reset --hard &&
72 echo 5 >other-file &&
73 git add other-file &&
74 test_tick &&
75 git commit -m other-file &&
76 git stash apply &&
77 test 3 = $(cat file) &&
78 test 1 = $(git show :file) &&
79 test 1 = $(git show HEAD:file)
82 test_expect_success 'apply stashed changes (including index)' '
83 git reset --hard HEAD^ &&
84 echo 6 > other-file &&
85 git add other-file &&
86 test_tick &&
87 git commit -m other-file &&
88 git stash apply --index &&
89 test 3 = $(cat file) &&
90 test 2 = $(git show :file) &&
91 test 1 = $(git show HEAD:file)
94 test_expect_success 'unstashing in a subdirectory' '
95 git reset --hard HEAD &&
96 mkdir subdir &&
98 cd subdir &&
99 git stash apply
103 test_expect_success 'drop top stash' '
104 git reset --hard &&
105 git stash list > stashlist1 &&
106 echo 7 > file &&
107 git stash &&
108 git stash drop &&
109 git stash list > stashlist2 &&
110 test_cmp stashlist1 stashlist2 &&
111 git stash apply &&
112 test 3 = $(cat file) &&
113 test 1 = $(git show :file) &&
114 test 1 = $(git show HEAD:file)
117 test_expect_success 'drop middle stash' '
118 git reset --hard &&
119 echo 8 > file &&
120 git stash &&
121 echo 9 > file &&
122 git stash &&
123 git stash drop stash@{1} &&
124 test 2 = $(git stash list | wc -l) &&
125 git stash apply &&
126 test 9 = $(cat file) &&
127 test 1 = $(git show :file) &&
128 test 1 = $(git show HEAD:file) &&
129 git reset --hard &&
130 git stash drop &&
131 git stash apply &&
132 test 3 = $(cat file) &&
133 test 1 = $(git show :file) &&
134 test 1 = $(git show HEAD:file)
137 test_expect_success 'stash pop' '
138 git reset --hard &&
139 git stash pop &&
140 test 3 = $(cat file) &&
141 test 1 = $(git show :file) &&
142 test 1 = $(git show HEAD:file) &&
143 test 0 = $(git stash list | wc -l)
146 cat > expect << EOF
147 diff --git a/file2 b/file2
148 new file mode 100644
149 index 0000000..1fe912c
150 --- /dev/null
151 +++ b/file2
152 @@ -0,0 +1 @@
153 +bar2
156 cat > expect1 << EOF
157 diff --git a/file b/file
158 index 257cc56..5716ca5 100644
159 --- a/file
160 +++ b/file
161 @@ -1 +1 @@
162 -foo
163 +bar
166 cat > expect2 << EOF
167 diff --git a/file b/file
168 index 7601807..5716ca5 100644
169 --- a/file
170 +++ b/file
171 @@ -1 +1 @@
172 -baz
173 +bar
174 diff --git a/file2 b/file2
175 new file mode 100644
176 index 0000000..1fe912c
177 --- /dev/null
178 +++ b/file2
179 @@ -0,0 +1 @@
180 +bar2
183 test_expect_success 'stash branch' '
184 echo foo > file &&
185 git commit file -m first &&
186 echo bar > file &&
187 echo bar2 > file2 &&
188 git add file2 &&
189 git stash &&
190 echo baz > file &&
191 git commit file -m second &&
192 git stash branch stashbranch &&
193 test refs/heads/stashbranch = $(git symbolic-ref HEAD) &&
194 test $(git rev-parse HEAD) = $(git rev-parse master^) &&
195 git diff --cached > output &&
196 test_cmp output expect &&
197 git diff > output &&
198 test_cmp output expect1 &&
199 git add file &&
200 git commit -m alternate\ second &&
201 git diff master..stashbranch > output &&
202 test_cmp output expect2 &&
203 test 0 = $(git stash list | wc -l)
206 test_expect_success 'apply -q is quiet' '
207 echo foo > file &&
208 git stash &&
209 git stash apply -q > output.out 2>&1 &&
210 test_must_be_empty output.out
213 test_expect_success 'save -q is quiet' '
214 git stash save --quiet > output.out 2>&1 &&
215 test_must_be_empty output.out
218 test_expect_success 'pop -q is quiet' '
219 git stash pop -q > output.out 2>&1 &&
220 test_must_be_empty output.out
223 test_expect_success 'pop -q --index works and is quiet' '
224 echo foo > file &&
225 git add file &&
226 git stash save --quiet &&
227 git stash pop -q --index > output.out 2>&1 &&
228 test foo = "$(git show :file)" &&
229 test_must_be_empty output.out
232 test_expect_success 'drop -q is quiet' '
233 git stash &&
234 git stash drop -q > output.out 2>&1 &&
235 test_must_be_empty output.out
238 test_expect_success 'stash -k' '
239 echo bar3 > file &&
240 echo bar4 > file2 &&
241 git add file2 &&
242 git stash -k &&
243 test bar,bar4 = $(cat file),$(cat file2)
246 test_expect_success 'stash --no-keep-index' '
247 echo bar33 > file &&
248 echo bar44 > file2 &&
249 git add file2 &&
250 git stash --no-keep-index &&
251 test bar,bar2 = $(cat file),$(cat file2)
254 test_expect_success 'stash --invalid-option' '
255 echo bar5 > file &&
256 echo bar6 > file2 &&
257 git add file2 &&
258 test_must_fail git stash --invalid-option &&
259 test_must_fail git stash save --invalid-option &&
260 test bar5,bar6 = $(cat file),$(cat file2) &&
261 git stash -- -message-starting-with-dash &&
262 test bar,bar2 = $(cat file),$(cat file2)
265 test_expect_success 'stash an added file' '
266 git reset --hard &&
267 echo new >file3 &&
268 git add file3 &&
269 git stash save "added file" &&
270 ! test -r file3 &&
271 git stash apply &&
272 test new = "$(cat file3)"
275 test_expect_success 'stash rm then recreate' '
276 git reset --hard &&
277 git rm file &&
278 echo bar7 >file &&
279 git stash save "rm then recreate" &&
280 test bar = "$(cat file)" &&
281 git stash apply &&
282 test bar7 = "$(cat file)"
285 test_expect_success 'stash rm and ignore' '
286 git reset --hard &&
287 git rm file &&
288 echo file >.gitignore &&
289 git stash save "rm and ignore" &&
290 test bar = "$(cat file)" &&
291 test file = "$(cat .gitignore)" &&
292 git stash apply &&
293 ! test -r file &&
294 test file = "$(cat .gitignore)"
297 test_expect_success 'stash rm and ignore (stage .gitignore)' '
298 git reset --hard &&
299 git rm file &&
300 echo file >.gitignore &&
301 git add .gitignore &&
302 git stash save "rm and ignore (stage .gitignore)" &&
303 test bar = "$(cat file)" &&
304 ! test -r .gitignore &&
305 git stash apply &&
306 ! test -r file &&
307 test file = "$(cat .gitignore)"
310 test_expect_success SYMLINKS 'stash file to symlink' '
311 git reset --hard &&
312 rm file &&
313 ln -s file2 file &&
314 git stash save "file to symlink" &&
315 test -f file &&
316 test bar = "$(cat file)" &&
317 git stash apply &&
318 case "$(ls -l file)" in *" file -> file2") :;; *) false;; esac
321 test_expect_success SYMLINKS 'stash file to symlink (stage rm)' '
322 git reset --hard &&
323 git rm file &&
324 ln -s file2 file &&
325 git stash save "file to symlink (stage rm)" &&
326 test -f file &&
327 test bar = "$(cat file)" &&
328 git stash apply &&
329 case "$(ls -l file)" in *" file -> file2") :;; *) false;; esac
332 test_expect_success SYMLINKS 'stash file to symlink (full stage)' '
333 git reset --hard &&
334 rm file &&
335 ln -s file2 file &&
336 git add file &&
337 git stash save "file to symlink (full stage)" &&
338 test -f file &&
339 test bar = "$(cat file)" &&
340 git stash apply &&
341 case "$(ls -l file)" in *" file -> file2") :;; *) false;; esac
344 # This test creates a commit with a symlink used for the following tests
346 test_expect_success 'stash symlink to file' '
347 git reset --hard &&
348 test_ln_s_add file filelink &&
349 git commit -m "Add symlink" &&
350 rm filelink &&
351 cp file filelink &&
352 git stash save "symlink to file"
355 test_expect_success SYMLINKS 'this must have re-created the symlink' '
356 test -h filelink &&
357 case "$(ls -l filelink)" in *" filelink -> file") :;; *) false;; esac
360 test_expect_success 'unstash must re-create the file' '
361 git stash apply &&
362 ! test -h filelink &&
363 test bar = "$(cat file)"
366 test_expect_success 'stash symlink to file (stage rm)' '
367 git reset --hard &&
368 git rm filelink &&
369 cp file filelink &&
370 git stash save "symlink to file (stage rm)"
373 test_expect_success SYMLINKS 'this must have re-created the symlink' '
374 test -h filelink &&
375 case "$(ls -l filelink)" in *" filelink -> file") :;; *) false;; esac
378 test_expect_success 'unstash must re-create the file' '
379 git stash apply &&
380 ! test -h filelink &&
381 test bar = "$(cat file)"
384 test_expect_success 'stash symlink to file (full stage)' '
385 git reset --hard &&
386 rm filelink &&
387 cp file filelink &&
388 git add filelink &&
389 git stash save "symlink to file (full stage)"
392 test_expect_success SYMLINKS 'this must have re-created the symlink' '
393 test -h filelink &&
394 case "$(ls -l filelink)" in *" filelink -> file") :;; *) false;; esac
397 test_expect_success 'unstash must re-create the file' '
398 git stash apply &&
399 ! test -h filelink &&
400 test bar = "$(cat file)"
403 test_expect_failure 'stash directory to file' '
404 git reset --hard &&
405 mkdir dir &&
406 echo foo >dir/file &&
407 git add dir/file &&
408 git commit -m "Add file in dir" &&
409 rm -fr dir &&
410 echo bar >dir &&
411 git stash save "directory to file" &&
412 test -d dir &&
413 test foo = "$(cat dir/file)" &&
414 test_must_fail git stash apply &&
415 test bar = "$(cat dir)" &&
416 git reset --soft HEAD^
419 test_expect_failure 'stash file to directory' '
420 git reset --hard &&
421 rm file &&
422 mkdir file &&
423 echo foo >file/file &&
424 git stash save "file to directory" &&
425 test -f file &&
426 test bar = "$(cat file)" &&
427 git stash apply &&
428 test -f file/file &&
429 test foo = "$(cat file/file)"
432 test_expect_success 'stash branch - no stashes on stack, stash-like argument' '
433 git stash clear &&
434 test_when_finished "git reset --hard HEAD" &&
435 git reset --hard &&
436 echo foo >> file &&
437 STASH_ID=$(git stash create) &&
438 git reset --hard &&
439 git stash branch stash-branch ${STASH_ID} &&
440 test_when_finished "git reset --hard HEAD && git checkout master && git branch -D stash-branch" &&
441 test $(git ls-files --modified | wc -l) -eq 1
444 test_expect_success 'stash branch - stashes on stack, stash-like argument' '
445 git stash clear &&
446 test_when_finished "git reset --hard HEAD" &&
447 git reset --hard &&
448 echo foo >> file &&
449 git stash &&
450 test_when_finished "git stash drop" &&
451 echo bar >> file &&
452 STASH_ID=$(git stash create) &&
453 git reset --hard &&
454 git stash branch stash-branch ${STASH_ID} &&
455 test_when_finished "git reset --hard HEAD && git checkout master && git branch -D stash-branch" &&
456 test $(git ls-files --modified | wc -l) -eq 1
459 test_expect_success 'stash show format defaults to --stat' '
460 git stash clear &&
461 test_when_finished "git reset --hard HEAD" &&
462 git reset --hard &&
463 echo foo >> file &&
464 git stash &&
465 test_when_finished "git stash drop" &&
466 echo bar >> file &&
467 STASH_ID=$(git stash create) &&
468 git reset --hard &&
469 cat >expected <<-EOF &&
470 file | 1 +
471 1 file changed, 1 insertion(+)
473 git stash show ${STASH_ID} >actual &&
474 test_i18ncmp expected actual
477 test_expect_success 'stash show - stashes on stack, stash-like argument' '
478 git stash clear &&
479 test_when_finished "git reset --hard HEAD" &&
480 git reset --hard &&
481 echo foo >> file &&
482 git stash &&
483 test_when_finished "git stash drop" &&
484 echo bar >> file &&
485 STASH_ID=$(git stash create) &&
486 git reset --hard &&
487 echo "1 0 file" >expected &&
488 git stash show --numstat ${STASH_ID} >actual &&
489 test_cmp expected actual
492 test_expect_success 'stash show -p - stashes on stack, stash-like argument' '
493 git stash clear &&
494 test_when_finished "git reset --hard HEAD" &&
495 git reset --hard &&
496 echo foo >> file &&
497 git stash &&
498 test_when_finished "git stash drop" &&
499 echo bar >> file &&
500 STASH_ID=$(git stash create) &&
501 git reset --hard &&
502 cat >expected <<-EOF &&
503 diff --git a/file b/file
504 index 7601807..935fbd3 100644
505 --- a/file
506 +++ b/file
507 @@ -1 +1,2 @@
509 +bar
511 git stash show -p ${STASH_ID} >actual &&
512 test_cmp expected actual
515 test_expect_success 'stash show - no stashes on stack, stash-like argument' '
516 git stash clear &&
517 test_when_finished "git reset --hard HEAD" &&
518 git reset --hard &&
519 echo foo >> file &&
520 STASH_ID=$(git stash create) &&
521 git reset --hard &&
522 echo "1 0 file" >expected &&
523 git stash show --numstat ${STASH_ID} >actual &&
524 test_cmp expected actual
527 test_expect_success 'stash show -p - no stashes on stack, stash-like argument' '
528 git stash clear &&
529 test_when_finished "git reset --hard HEAD" &&
530 git reset --hard &&
531 echo foo >> file &&
532 STASH_ID=$(git stash create) &&
533 git reset --hard &&
534 cat >expected <<-EOF &&
535 diff --git a/file b/file
536 index 7601807..71b52c4 100644
537 --- a/file
538 +++ b/file
539 @@ -1 +1,2 @@
541 +foo
543 git stash show -p ${STASH_ID} >actual &&
544 test_cmp expected actual
547 test_expect_success 'stash drop - fail early if specified stash is not a stash reference' '
548 git stash clear &&
549 test_when_finished "git reset --hard HEAD && git stash clear" &&
550 git reset --hard &&
551 echo foo > file &&
552 git stash &&
553 echo bar > file &&
554 git stash &&
555 test_must_fail git stash drop $(git rev-parse stash@{0}) &&
556 git stash pop &&
557 test bar = "$(cat file)" &&
558 git reset --hard HEAD
561 test_expect_success 'stash pop - fail early if specified stash is not a stash reference' '
562 git stash clear &&
563 test_when_finished "git reset --hard HEAD && git stash clear" &&
564 git reset --hard &&
565 echo foo > file &&
566 git stash &&
567 echo bar > file &&
568 git stash &&
569 test_must_fail git stash pop $(git rev-parse stash@{0}) &&
570 git stash pop &&
571 test bar = "$(cat file)" &&
572 git reset --hard HEAD
575 test_expect_success 'ref with non-existent reflog' '
576 git stash clear &&
577 echo bar5 > file &&
578 echo bar6 > file2 &&
579 git add file2 &&
580 git stash &&
581 test_must_fail git rev-parse --quiet --verify does-not-exist &&
582 test_must_fail git stash drop does-not-exist &&
583 test_must_fail git stash drop does-not-exist@{0} &&
584 test_must_fail git stash pop does-not-exist &&
585 test_must_fail git stash pop does-not-exist@{0} &&
586 test_must_fail git stash apply does-not-exist &&
587 test_must_fail git stash apply does-not-exist@{0} &&
588 test_must_fail git stash show does-not-exist &&
589 test_must_fail git stash show does-not-exist@{0} &&
590 test_must_fail git stash branch tmp does-not-exist &&
591 test_must_fail git stash branch tmp does-not-exist@{0} &&
592 git stash drop
595 test_expect_success 'invalid ref of the form stash@{n}, n >= N' '
596 git stash clear &&
597 test_must_fail git stash drop stash@{0} &&
598 echo bar5 > file &&
599 echo bar6 > file2 &&
600 git add file2 &&
601 git stash &&
602 test_must_fail git stash drop stash@{1} &&
603 test_must_fail git stash pop stash@{1} &&
604 test_must_fail git stash apply stash@{1} &&
605 test_must_fail git stash show stash@{1} &&
606 test_must_fail git stash branch tmp stash@{1} &&
607 git stash drop
610 test_expect_success 'stash branch should not drop the stash if the branch exists' '
611 git stash clear &&
612 echo foo >file &&
613 git add file &&
614 git commit -m initial &&
615 echo bar >file &&
616 git stash &&
617 test_must_fail git stash branch master stash@{0} &&
618 git rev-parse stash@{0} --
621 test_expect_success 'stash apply shows status same as git status (relative to current directory)' '
622 git stash clear &&
623 echo 1 >subdir/subfile1 &&
624 echo 2 >subdir/subfile2 &&
625 git add subdir/subfile1 &&
626 git commit -m subdir &&
628 cd subdir &&
629 echo x >subfile1 &&
630 echo x >../file &&
631 git status >../expect &&
632 git stash &&
633 sane_unset GIT_MERGE_VERBOSITY &&
634 git stash apply
636 sed -e 1,2d >actual && # drop "Saved..." and "HEAD is now..."
637 test_i18ncmp expect actual
640 cat > expect << EOF
641 diff --git a/HEAD b/HEAD
642 new file mode 100644
643 index 0000000..fe0cbee
644 --- /dev/null
645 +++ b/HEAD
646 @@ -0,0 +1 @@
647 +file-not-a-ref
650 test_expect_success 'stash where working directory contains "HEAD" file' '
651 git stash clear &&
652 git reset --hard &&
653 echo file-not-a-ref > HEAD &&
654 git add HEAD &&
655 test_tick &&
656 git stash &&
657 git diff-files --quiet &&
658 git diff-index --cached --quiet HEAD &&
659 test "$(git rev-parse stash^)" = "$(git rev-parse HEAD)" &&
660 git diff stash^..stash > output &&
661 test_cmp output expect
664 test_expect_success 'store called with invalid commit' '
665 test_must_fail git stash store foo
668 test_expect_success 'store updates stash ref and reflog' '
669 git stash clear &&
670 git reset --hard &&
671 echo quux >bazzy &&
672 git add bazzy &&
673 STASH_ID=$(git stash create) &&
674 git reset --hard &&
675 ! grep quux bazzy &&
676 git stash store -m quuxery $STASH_ID &&
677 test $(cat .git/refs/stash) = $STASH_ID &&
678 grep $STASH_ID .git/logs/refs/stash &&
679 git stash pop &&
680 grep quux bazzy
683 test_expect_success 'handle stash specification with spaces' '
684 git stash clear &&
685 echo pig >file &&
686 git stash &&
687 stamp=$(git log -g --format="%cd" -1 refs/stash) &&
688 test_tick &&
689 echo cow >file &&
690 git stash &&
691 git stash apply "stash@{$stamp}" &&
692 grep pig file
695 test_expect_success 'setup stash with index and worktree changes' '
696 git stash clear &&
697 git reset --hard &&
698 echo index >file &&
699 git add file &&
700 echo working >file &&
701 git stash
704 test_expect_success 'stash list implies --first-parent -m' '
705 cat >expect <<-EOF &&
706 stash@{0}
708 diff --git a/file b/file
709 index 257cc56..d26b33d 100644
710 --- a/file
711 +++ b/file
712 @@ -1 +1 @@
713 -foo
714 +working
716 git stash list --format=%gd -p >actual &&
717 test_cmp expect actual
720 test_expect_success 'stash list --cc shows combined diff' '
721 cat >expect <<-\EOF &&
722 stash@{0}
724 diff --cc file
725 index 257cc56,9015a7a..d26b33d
726 --- a/file
727 +++ b/file
728 @@@ -1,1 -1,1 +1,1 @@@
729 - foo
730 -index
731 ++working
733 git stash list --format=%gd -p --cc >actual &&
734 test_cmp expect actual
737 test_done