Imported Upstream version 2.4.4
[platform/upstream/git.git] / t / t3903-stash.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2007 Johannes E Schindelin
4 #
5
6 test_description='Test git stash'
7
8 . ./test-lib.sh
9
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
24 '
25
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 @@
32 -2
33 +3
34 EOF
35
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
40 '
41
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
46 '
47
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
53 '
54
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
60 '
61
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
68 '
69
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)
80 '
81
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)
92 '
93
94 test_expect_success 'unstashing in a subdirectory' '
95         git reset --hard HEAD &&
96         mkdir subdir &&
97         (
98                 cd subdir &&
99                 git stash apply
100         )
101 '
102
103 test_expect_success 'stash drop complains of extra options' '
104         test_must_fail git stash drop --foo
105 '
106
107 test_expect_success 'drop top stash' '
108         git reset --hard &&
109         git stash list > stashlist1 &&
110         echo 7 > file &&
111         git stash &&
112         git stash drop &&
113         git stash list > stashlist2 &&
114         test_cmp stashlist1 stashlist2 &&
115         git stash apply &&
116         test 3 = $(cat file) &&
117         test 1 = $(git show :file) &&
118         test 1 = $(git show HEAD:file)
119 '
120
121 test_expect_success 'drop middle stash' '
122         git reset --hard &&
123         echo 8 > file &&
124         git stash &&
125         echo 9 > file &&
126         git stash &&
127         git stash drop stash@{1} &&
128         test 2 = $(git stash list | wc -l) &&
129         git stash apply &&
130         test 9 = $(cat file) &&
131         test 1 = $(git show :file) &&
132         test 1 = $(git show HEAD:file) &&
133         git reset --hard &&
134         git stash drop &&
135         git stash apply &&
136         test 3 = $(cat file) &&
137         test 1 = $(git show :file) &&
138         test 1 = $(git show HEAD:file)
139 '
140
141 test_expect_success 'stash pop' '
142         git reset --hard &&
143         git stash pop &&
144         test 3 = $(cat file) &&
145         test 1 = $(git show :file) &&
146         test 1 = $(git show HEAD:file) &&
147         test 0 = $(git stash list | wc -l)
148 '
149
150 cat > expect << EOF
151 diff --git a/file2 b/file2
152 new file mode 100644
153 index 0000000..1fe912c
154 --- /dev/null
155 +++ b/file2
156 @@ -0,0 +1 @@
157 +bar2
158 EOF
159
160 cat > expect1 << EOF
161 diff --git a/file b/file
162 index 257cc56..5716ca5 100644
163 --- a/file
164 +++ b/file
165 @@ -1 +1 @@
166 -foo
167 +bar
168 EOF
169
170 cat > expect2 << EOF
171 diff --git a/file b/file
172 index 7601807..5716ca5 100644
173 --- a/file
174 +++ b/file
175 @@ -1 +1 @@
176 -baz
177 +bar
178 diff --git a/file2 b/file2
179 new file mode 100644
180 index 0000000..1fe912c
181 --- /dev/null
182 +++ b/file2
183 @@ -0,0 +1 @@
184 +bar2
185 EOF
186
187 test_expect_success 'stash branch' '
188         echo foo > file &&
189         git commit file -m first &&
190         echo bar > file &&
191         echo bar2 > file2 &&
192         git add file2 &&
193         git stash &&
194         echo baz > file &&
195         git commit file -m second &&
196         git stash branch stashbranch &&
197         test refs/heads/stashbranch = $(git symbolic-ref HEAD) &&
198         test $(git rev-parse HEAD) = $(git rev-parse master^) &&
199         git diff --cached > output &&
200         test_cmp output expect &&
201         git diff > output &&
202         test_cmp output expect1 &&
203         git add file &&
204         git commit -m alternate\ second &&
205         git diff master..stashbranch > output &&
206         test_cmp output expect2 &&
207         test 0 = $(git stash list | wc -l)
208 '
209
210 test_expect_success 'apply -q is quiet' '
211         echo foo > file &&
212         git stash &&
213         git stash apply -q > output.out 2>&1 &&
214         test_must_be_empty output.out
215 '
216
217 test_expect_success 'save -q is quiet' '
218         git stash save --quiet > output.out 2>&1 &&
219         test_must_be_empty output.out
220 '
221
222 test_expect_success 'pop -q is quiet' '
223         git stash pop -q > output.out 2>&1 &&
224         test_must_be_empty output.out
225 '
226
227 test_expect_success 'pop -q --index works and is quiet' '
228         echo foo > file &&
229         git add file &&
230         git stash save --quiet &&
231         git stash pop -q --index > output.out 2>&1 &&
232         test foo = "$(git show :file)" &&
233         test_must_be_empty output.out
234 '
235
236 test_expect_success 'drop -q is quiet' '
237         git stash &&
238         git stash drop -q > output.out 2>&1 &&
239         test_must_be_empty output.out
240 '
241
242 test_expect_success 'stash -k' '
243         echo bar3 > file &&
244         echo bar4 > file2 &&
245         git add file2 &&
246         git stash -k &&
247         test bar,bar4 = $(cat file),$(cat file2)
248 '
249
250 test_expect_success 'stash --no-keep-index' '
251         echo bar33 > file &&
252         echo bar44 > file2 &&
253         git add file2 &&
254         git stash --no-keep-index &&
255         test bar,bar2 = $(cat file),$(cat file2)
256 '
257
258 test_expect_success 'stash --invalid-option' '
259         echo bar5 > file &&
260         echo bar6 > file2 &&
261         git add file2 &&
262         test_must_fail git stash --invalid-option &&
263         test_must_fail git stash save --invalid-option &&
264         test bar5,bar6 = $(cat file),$(cat file2) &&
265         git stash -- -message-starting-with-dash &&
266         test bar,bar2 = $(cat file),$(cat file2)
267 '
268
269 test_expect_success 'stash an added file' '
270         git reset --hard &&
271         echo new >file3 &&
272         git add file3 &&
273         git stash save "added file" &&
274         ! test -r file3 &&
275         git stash apply &&
276         test new = "$(cat file3)"
277 '
278
279 test_expect_success 'stash rm then recreate' '
280         git reset --hard &&
281         git rm file &&
282         echo bar7 >file &&
283         git stash save "rm then recreate" &&
284         test bar = "$(cat file)" &&
285         git stash apply &&
286         test bar7 = "$(cat file)"
287 '
288
289 test_expect_success 'stash rm and ignore' '
290         git reset --hard &&
291         git rm file &&
292         echo file >.gitignore &&
293         git stash save "rm and ignore" &&
294         test bar = "$(cat file)" &&
295         test file = "$(cat .gitignore)" &&
296         git stash apply &&
297         ! test -r file &&
298         test file = "$(cat .gitignore)"
299 '
300
301 test_expect_success 'stash rm and ignore (stage .gitignore)' '
302         git reset --hard &&
303         git rm file &&
304         echo file >.gitignore &&
305         git add .gitignore &&
306         git stash save "rm and ignore (stage .gitignore)" &&
307         test bar = "$(cat file)" &&
308         ! test -r .gitignore &&
309         git stash apply &&
310         ! test -r file &&
311         test file = "$(cat .gitignore)"
312 '
313
314 test_expect_success SYMLINKS 'stash file to symlink' '
315         git reset --hard &&
316         rm file &&
317         ln -s file2 file &&
318         git stash save "file to symlink" &&
319         test -f file &&
320         test bar = "$(cat file)" &&
321         git stash apply &&
322         case "$(ls -l file)" in *" file -> file2") :;; *) false;; esac
323 '
324
325 test_expect_success SYMLINKS 'stash file to symlink (stage rm)' '
326         git reset --hard &&
327         git rm file &&
328         ln -s file2 file &&
329         git stash save "file to symlink (stage rm)" &&
330         test -f file &&
331         test bar = "$(cat file)" &&
332         git stash apply &&
333         case "$(ls -l file)" in *" file -> file2") :;; *) false;; esac
334 '
335
336 test_expect_success SYMLINKS 'stash file to symlink (full stage)' '
337         git reset --hard &&
338         rm file &&
339         ln -s file2 file &&
340         git add file &&
341         git stash save "file to symlink (full stage)" &&
342         test -f file &&
343         test bar = "$(cat file)" &&
344         git stash apply &&
345         case "$(ls -l file)" in *" file -> file2") :;; *) false;; esac
346 '
347
348 # This test creates a commit with a symlink used for the following tests
349
350 test_expect_success 'stash symlink to file' '
351         git reset --hard &&
352         test_ln_s_add file filelink &&
353         git commit -m "Add symlink" &&
354         rm filelink &&
355         cp file filelink &&
356         git stash save "symlink to file"
357 '
358
359 test_expect_success SYMLINKS 'this must have re-created the symlink' '
360         test -h filelink &&
361         case "$(ls -l filelink)" in *" filelink -> file") :;; *) false;; esac
362 '
363
364 test_expect_success 'unstash must re-create the file' '
365         git stash apply &&
366         ! test -h filelink &&
367         test bar = "$(cat file)"
368 '
369
370 test_expect_success 'stash symlink to file (stage rm)' '
371         git reset --hard &&
372         git rm filelink &&
373         cp file filelink &&
374         git stash save "symlink to file (stage rm)"
375 '
376
377 test_expect_success SYMLINKS 'this must have re-created the symlink' '
378         test -h filelink &&
379         case "$(ls -l filelink)" in *" filelink -> file") :;; *) false;; esac
380 '
381
382 test_expect_success 'unstash must re-create the file' '
383         git stash apply &&
384         ! test -h filelink &&
385         test bar = "$(cat file)"
386 '
387
388 test_expect_success 'stash symlink to file (full stage)' '
389         git reset --hard &&
390         rm filelink &&
391         cp file filelink &&
392         git add filelink &&
393         git stash save "symlink to file (full stage)"
394 '
395
396 test_expect_success SYMLINKS 'this must have re-created the symlink' '
397         test -h filelink &&
398         case "$(ls -l filelink)" in *" filelink -> file") :;; *) false;; esac
399 '
400
401 test_expect_success 'unstash must re-create the file' '
402         git stash apply &&
403         ! test -h filelink &&
404         test bar = "$(cat file)"
405 '
406
407 test_expect_failure 'stash directory to file' '
408         git reset --hard &&
409         mkdir dir &&
410         echo foo >dir/file &&
411         git add dir/file &&
412         git commit -m "Add file in dir" &&
413         rm -fr dir &&
414         echo bar >dir &&
415         git stash save "directory to file" &&
416         test -d dir &&
417         test foo = "$(cat dir/file)" &&
418         test_must_fail git stash apply &&
419         test bar = "$(cat dir)" &&
420         git reset --soft HEAD^
421 '
422
423 test_expect_failure 'stash file to directory' '
424         git reset --hard &&
425         rm file &&
426         mkdir file &&
427         echo foo >file/file &&
428         git stash save "file to directory" &&
429         test -f file &&
430         test bar = "$(cat file)" &&
431         git stash apply &&
432         test -f file/file &&
433         test foo = "$(cat file/file)"
434 '
435
436 test_expect_success 'stash branch - no stashes on stack, stash-like argument' '
437         git stash clear &&
438         test_when_finished "git reset --hard HEAD" &&
439         git reset --hard &&
440         echo foo >> file &&
441         STASH_ID=$(git stash create) &&
442         git reset --hard &&
443         git stash branch stash-branch ${STASH_ID} &&
444         test_when_finished "git reset --hard HEAD && git checkout master && git branch -D stash-branch" &&
445         test $(git ls-files --modified | wc -l) -eq 1
446 '
447
448 test_expect_success 'stash branch - stashes on stack, stash-like argument' '
449         git stash clear &&
450         test_when_finished "git reset --hard HEAD" &&
451         git reset --hard &&
452         echo foo >> file &&
453         git stash &&
454         test_when_finished "git stash drop" &&
455         echo bar >> file &&
456         STASH_ID=$(git stash create) &&
457         git reset --hard &&
458         git stash branch stash-branch ${STASH_ID} &&
459         test_when_finished "git reset --hard HEAD && git checkout master && git branch -D stash-branch" &&
460         test $(git ls-files --modified | wc -l) -eq 1
461 '
462
463 test_expect_success 'stash show format defaults to --stat' '
464         git stash clear &&
465         test_when_finished "git reset --hard HEAD" &&
466         git reset --hard &&
467         echo foo >> file &&
468         git stash &&
469         test_when_finished "git stash drop" &&
470         echo bar >> file &&
471         STASH_ID=$(git stash create) &&
472         git reset --hard &&
473         cat >expected <<-EOF &&
474          file | 1 +
475          1 file changed, 1 insertion(+)
476         EOF
477         git stash show ${STASH_ID} >actual &&
478         test_i18ncmp expected actual
479 '
480
481 test_expect_success 'stash show - stashes on stack, stash-like argument' '
482         git stash clear &&
483         test_when_finished "git reset --hard HEAD" &&
484         git reset --hard &&
485         echo foo >> file &&
486         git stash &&
487         test_when_finished "git stash drop" &&
488         echo bar >> file &&
489         STASH_ID=$(git stash create) &&
490         git reset --hard &&
491         echo "1 0       file" >expected &&
492         git stash show --numstat ${STASH_ID} >actual &&
493         test_cmp expected actual
494 '
495
496 test_expect_success 'stash show -p - stashes on stack, stash-like argument' '
497         git stash clear &&
498         test_when_finished "git reset --hard HEAD" &&
499         git reset --hard &&
500         echo foo >> file &&
501         git stash &&
502         test_when_finished "git stash drop" &&
503         echo bar >> file &&
504         STASH_ID=$(git stash create) &&
505         git reset --hard &&
506         cat >expected <<-EOF &&
507         diff --git a/file b/file
508         index 7601807..935fbd3 100644
509         --- a/file
510         +++ b/file
511         @@ -1 +1,2 @@
512          baz
513         +bar
514         EOF
515         git stash show -p ${STASH_ID} >actual &&
516         test_cmp expected actual
517 '
518
519 test_expect_success 'stash show - no stashes on stack, stash-like argument' '
520         git stash clear &&
521         test_when_finished "git reset --hard HEAD" &&
522         git reset --hard &&
523         echo foo >> file &&
524         STASH_ID=$(git stash create) &&
525         git reset --hard &&
526         echo "1 0       file" >expected &&
527         git stash show --numstat ${STASH_ID} >actual &&
528         test_cmp expected actual
529 '
530
531 test_expect_success 'stash show -p - no stashes on stack, stash-like argument' '
532         git stash clear &&
533         test_when_finished "git reset --hard HEAD" &&
534         git reset --hard &&
535         echo foo >> file &&
536         STASH_ID=$(git stash create) &&
537         git reset --hard &&
538         cat >expected <<-EOF &&
539         diff --git a/file b/file
540         index 7601807..71b52c4 100644
541         --- a/file
542         +++ b/file
543         @@ -1 +1,2 @@
544          baz
545         +foo
546         EOF
547         git stash show -p ${STASH_ID} >actual &&
548         test_cmp expected actual
549 '
550
551 test_expect_success 'stash drop - fail early if specified stash is not a stash reference' '
552         git stash clear &&
553         test_when_finished "git reset --hard HEAD && git stash clear" &&
554         git reset --hard &&
555         echo foo > file &&
556         git stash &&
557         echo bar > file &&
558         git stash &&
559         test_must_fail git stash drop $(git rev-parse stash@{0}) &&
560         git stash pop &&
561         test bar = "$(cat file)" &&
562         git reset --hard HEAD
563 '
564
565 test_expect_success 'stash pop - fail early if specified stash is not a stash reference' '
566         git stash clear &&
567         test_when_finished "git reset --hard HEAD && git stash clear" &&
568         git reset --hard &&
569         echo foo > file &&
570         git stash &&
571         echo bar > file &&
572         git stash &&
573         test_must_fail git stash pop $(git rev-parse stash@{0}) &&
574         git stash pop &&
575         test bar = "$(cat file)" &&
576         git reset --hard HEAD
577 '
578
579 test_expect_success 'ref with non-existent reflog' '
580         git stash clear &&
581         echo bar5 > file &&
582         echo bar6 > file2 &&
583         git add file2 &&
584         git stash &&
585         test_must_fail git rev-parse --quiet --verify does-not-exist &&
586         test_must_fail git stash drop does-not-exist &&
587         test_must_fail git stash drop does-not-exist@{0} &&
588         test_must_fail git stash pop does-not-exist &&
589         test_must_fail git stash pop does-not-exist@{0} &&
590         test_must_fail git stash apply does-not-exist &&
591         test_must_fail git stash apply does-not-exist@{0} &&
592         test_must_fail git stash show does-not-exist &&
593         test_must_fail git stash show does-not-exist@{0} &&
594         test_must_fail git stash branch tmp does-not-exist &&
595         test_must_fail git stash branch tmp does-not-exist@{0} &&
596         git stash drop
597 '
598
599 test_expect_success 'invalid ref of the form stash@{n}, n >= N' '
600         git stash clear &&
601         test_must_fail git stash drop stash@{0} &&
602         echo bar5 > file &&
603         echo bar6 > file2 &&
604         git add file2 &&
605         git stash &&
606         test_must_fail git stash drop stash@{1} &&
607         test_must_fail git stash pop stash@{1} &&
608         test_must_fail git stash apply stash@{1} &&
609         test_must_fail git stash show stash@{1} &&
610         test_must_fail git stash branch tmp stash@{1} &&
611         git stash drop
612 '
613
614 test_expect_success 'stash branch should not drop the stash if the branch exists' '
615         git stash clear &&
616         echo foo >file &&
617         git add file &&
618         git commit -m initial &&
619         echo bar >file &&
620         git stash &&
621         test_must_fail git stash branch master stash@{0} &&
622         git rev-parse stash@{0} --
623 '
624
625 test_expect_success 'stash apply shows status same as git status (relative to current directory)' '
626         git stash clear &&
627         echo 1 >subdir/subfile1 &&
628         echo 2 >subdir/subfile2 &&
629         git add subdir/subfile1 &&
630         git commit -m subdir &&
631         (
632                 cd subdir &&
633                 echo x >subfile1 &&
634                 echo x >../file &&
635                 git status >../expect &&
636                 git stash &&
637                 sane_unset GIT_MERGE_VERBOSITY &&
638                 git stash apply
639         ) |
640         sed -e 1,2d >actual && # drop "Saved..." and "HEAD is now..."
641         test_i18ncmp expect actual
642 '
643
644 cat > expect << EOF
645 diff --git a/HEAD b/HEAD
646 new file mode 100644
647 index 0000000..fe0cbee
648 --- /dev/null
649 +++ b/HEAD
650 @@ -0,0 +1 @@
651 +file-not-a-ref
652 EOF
653
654 test_expect_success 'stash where working directory contains "HEAD" file' '
655         git stash clear &&
656         git reset --hard &&
657         echo file-not-a-ref > HEAD &&
658         git add HEAD &&
659         test_tick &&
660         git stash &&
661         git diff-files --quiet &&
662         git diff-index --cached --quiet HEAD &&
663         test "$(git rev-parse stash^)" = "$(git rev-parse HEAD)" &&
664         git diff stash^..stash > output &&
665         test_cmp output expect
666 '
667
668 test_expect_success 'store called with invalid commit' '
669         test_must_fail git stash store foo
670 '
671
672 test_expect_success 'store updates stash ref and reflog' '
673         git stash clear &&
674         git reset --hard &&
675         echo quux >bazzy &&
676         git add bazzy &&
677         STASH_ID=$(git stash create) &&
678         git reset --hard &&
679         ! grep quux bazzy &&
680         git stash store -m quuxery $STASH_ID &&
681         test $(cat .git/refs/stash) = $STASH_ID &&
682         grep $STASH_ID .git/logs/refs/stash &&
683         git stash pop &&
684         grep quux bazzy
685 '
686
687 test_expect_success 'handle stash specification with spaces' '
688         git stash clear &&
689         echo pig >file &&
690         git stash &&
691         stamp=$(git log -g --format="%cd" -1 refs/stash) &&
692         test_tick &&
693         echo cow >file &&
694         git stash &&
695         git stash apply "stash@{$stamp}" &&
696         grep pig file
697 '
698
699 test_expect_success 'setup stash with index and worktree changes' '
700         git stash clear &&
701         git reset --hard &&
702         echo index >file &&
703         git add file &&
704         echo working >file &&
705         git stash
706 '
707
708 test_expect_success 'stash list implies --first-parent -m' '
709         cat >expect <<-EOF &&
710         stash@{0}
711
712         diff --git a/file b/file
713         index 257cc56..d26b33d 100644
714         --- a/file
715         +++ b/file
716         @@ -1 +1 @@
717         -foo
718         +working
719         EOF
720         git stash list --format=%gd -p >actual &&
721         test_cmp expect actual
722 '
723
724 test_expect_success 'stash list --cc shows combined diff' '
725         cat >expect <<-\EOF &&
726         stash@{0}
727
728         diff --cc file
729         index 257cc56,9015a7a..d26b33d
730         --- a/file
731         +++ b/file
732         @@@ -1,1 -1,1 +1,1 @@@
733         - foo
734          -index
735         ++working
736         EOF
737         git stash list --format=%gd -p --cc >actual &&
738         test_cmp expect actual
739 '
740
741 test_done