stash: convert apply to builtin
[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 expect output
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 does not need clean working directory' '
49         echo 4 >other-file &&
50         git stash apply &&
51         echo 3 >expect &&
52         test_cmp expect file
53 '
54
55 test_expect_success 'apply does not clobber working directory changes' '
56         git reset --hard &&
57         echo 4 >file &&
58         test_must_fail git stash apply &&
59         echo 4 >expect &&
60         test_cmp expect file
61 '
62
63 test_expect_success 'apply stashed changes' '
64         git reset --hard &&
65         echo 5 >other-file &&
66         git add other-file &&
67         test_tick &&
68         git commit -m other-file &&
69         git stash apply &&
70         test 3 = $(cat file) &&
71         test 1 = $(git show :file) &&
72         test 1 = $(git show HEAD:file)
73 '
74
75 test_expect_success 'apply stashed changes (including index)' '
76         git reset --hard HEAD^ &&
77         echo 6 >other-file &&
78         git add other-file &&
79         test_tick &&
80         git commit -m other-file &&
81         git stash apply --index &&
82         test 3 = $(cat file) &&
83         test 2 = $(git show :file) &&
84         test 1 = $(git show HEAD:file)
85 '
86
87 test_expect_success 'unstashing in a subdirectory' '
88         git reset --hard HEAD &&
89         mkdir subdir &&
90         (
91                 cd subdir &&
92                 git stash apply
93         )
94 '
95
96 test_expect_success 'stash drop complains of extra options' '
97         test_must_fail git stash drop --foo
98 '
99
100 test_expect_success 'drop top stash' '
101         git reset --hard &&
102         git stash list >expected &&
103         echo 7 >file &&
104         git stash &&
105         git stash drop &&
106         git stash list >actual &&
107         test_cmp expected actual &&
108         git stash apply &&
109         test 3 = $(cat file) &&
110         test 1 = $(git show :file) &&
111         test 1 = $(git show HEAD:file)
112 '
113
114 test_expect_success 'drop middle stash' '
115         git reset --hard &&
116         echo 8 >file &&
117         git stash &&
118         echo 9 >file &&
119         git stash &&
120         git stash drop stash@{1} &&
121         test 2 = $(git stash list | wc -l) &&
122         git stash apply &&
123         test 9 = $(cat file) &&
124         test 1 = $(git show :file) &&
125         test 1 = $(git show HEAD:file) &&
126         git reset --hard &&
127         git stash drop &&
128         git stash apply &&
129         test 3 = $(cat file) &&
130         test 1 = $(git show :file) &&
131         test 1 = $(git show HEAD:file)
132 '
133
134 test_expect_success 'drop middle stash by index' '
135         git reset --hard &&
136         echo 8 >file &&
137         git stash &&
138         echo 9 >file &&
139         git stash &&
140         git stash drop 1 &&
141         test 2 = $(git stash list | wc -l) &&
142         git stash apply &&
143         test 9 = $(cat file) &&
144         test 1 = $(git show :file) &&
145         test 1 = $(git show HEAD:file) &&
146         git reset --hard &&
147         git stash drop &&
148         git stash apply &&
149         test 3 = $(cat file) &&
150         test 1 = $(git show :file) &&
151         test 1 = $(git show HEAD:file)
152 '
153
154 test_expect_success 'stash pop' '
155         git reset --hard &&
156         git stash pop &&
157         test 3 = $(cat file) &&
158         test 1 = $(git show :file) &&
159         test 1 = $(git show HEAD:file) &&
160         test 0 = $(git stash list | wc -l)
161 '
162
163 cat >expect <<EOF
164 diff --git a/file2 b/file2
165 new file mode 100644
166 index 0000000..1fe912c
167 --- /dev/null
168 +++ b/file2
169 @@ -0,0 +1 @@
170 +bar2
171 EOF
172
173 cat >expect1 <<EOF
174 diff --git a/file b/file
175 index 257cc56..5716ca5 100644
176 --- a/file
177 +++ b/file
178 @@ -1 +1 @@
179 -foo
180 +bar
181 EOF
182
183 cat >expect2 <<EOF
184 diff --git a/file b/file
185 index 7601807..5716ca5 100644
186 --- a/file
187 +++ b/file
188 @@ -1 +1 @@
189 -baz
190 +bar
191 diff --git a/file2 b/file2
192 new file mode 100644
193 index 0000000..1fe912c
194 --- /dev/null
195 +++ b/file2
196 @@ -0,0 +1 @@
197 +bar2
198 EOF
199
200 test_expect_success 'stash branch' '
201         echo foo >file &&
202         git commit file -m first &&
203         echo bar >file &&
204         echo bar2 >file2 &&
205         git add file2 &&
206         git stash &&
207         echo baz >file &&
208         git commit file -m second &&
209         git stash branch stashbranch &&
210         test refs/heads/stashbranch = $(git symbolic-ref HEAD) &&
211         test $(git rev-parse HEAD) = $(git rev-parse master^) &&
212         git diff --cached >output &&
213         test_cmp expect output &&
214         git diff >output &&
215         test_cmp expect1 output &&
216         git add file &&
217         git commit -m alternate\ second &&
218         git diff master..stashbranch >output &&
219         test_cmp output expect2 &&
220         test 0 = $(git stash list | wc -l)
221 '
222
223 test_expect_success 'apply -q is quiet' '
224         echo foo >file &&
225         git stash &&
226         git stash apply -q >output.out 2>&1 &&
227         test_must_be_empty output.out
228 '
229
230 test_expect_success 'save -q is quiet' '
231         git stash save --quiet >output.out 2>&1 &&
232         test_must_be_empty output.out
233 '
234
235 test_expect_success 'pop -q is quiet' '
236         git stash pop -q >output.out 2>&1 &&
237         test_must_be_empty output.out
238 '
239
240 test_expect_success 'pop -q --index works and is quiet' '
241         echo foo >file &&
242         git add file &&
243         git stash save --quiet &&
244         git stash pop -q --index >output.out 2>&1 &&
245         test foo = "$(git show :file)" &&
246         test_must_be_empty output.out
247 '
248
249 test_expect_success 'drop -q is quiet' '
250         git stash &&
251         git stash drop -q >output.out 2>&1 &&
252         test_must_be_empty output.out
253 '
254
255 test_expect_success 'stash -k' '
256         echo bar3 >file &&
257         echo bar4 >file2 &&
258         git add file2 &&
259         git stash -k &&
260         test bar,bar4 = $(cat file),$(cat file2)
261 '
262
263 test_expect_success 'stash --no-keep-index' '
264         echo bar33 >file &&
265         echo bar44 >file2 &&
266         git add file2 &&
267         git stash --no-keep-index &&
268         test bar,bar2 = $(cat file),$(cat file2)
269 '
270
271 test_expect_success 'stash --invalid-option' '
272         echo bar5 >file &&
273         echo bar6 >file2 &&
274         git add file2 &&
275         test_must_fail git stash --invalid-option &&
276         test_must_fail git stash save --invalid-option &&
277         test bar5,bar6 = $(cat file),$(cat file2)
278 '
279
280 test_expect_success 'stash an added file' '
281         git reset --hard &&
282         echo new >file3 &&
283         git add file3 &&
284         git stash save "added file" &&
285         ! test -r file3 &&
286         git stash apply &&
287         test new = "$(cat file3)"
288 '
289
290 test_expect_success 'stash --intent-to-add file' '
291         git reset --hard &&
292         echo new >file4 &&
293         git add --intent-to-add file4 &&
294         test_when_finished "git rm -f file4" &&
295         test_must_fail git stash
296 '
297
298 test_expect_success 'stash rm then recreate' '
299         git reset --hard &&
300         git rm file &&
301         echo bar7 >file &&
302         git stash save "rm then recreate" &&
303         test bar = "$(cat file)" &&
304         git stash apply &&
305         test bar7 = "$(cat file)"
306 '
307
308 test_expect_success 'stash rm and ignore' '
309         git reset --hard &&
310         git rm file &&
311         echo file >.gitignore &&
312         git stash save "rm and ignore" &&
313         test bar = "$(cat file)" &&
314         test file = "$(cat .gitignore)" &&
315         git stash apply &&
316         ! test -r file &&
317         test file = "$(cat .gitignore)"
318 '
319
320 test_expect_success 'stash rm and ignore (stage .gitignore)' '
321         git reset --hard &&
322         git rm file &&
323         echo file >.gitignore &&
324         git add .gitignore &&
325         git stash save "rm and ignore (stage .gitignore)" &&
326         test bar = "$(cat file)" &&
327         ! test -r .gitignore &&
328         git stash apply &&
329         ! test -r file &&
330         test file = "$(cat .gitignore)"
331 '
332
333 test_expect_success SYMLINKS 'stash file to symlink' '
334         git reset --hard &&
335         rm file &&
336         ln -s file2 file &&
337         git stash save "file to symlink" &&
338         test -f file &&
339         test bar = "$(cat file)" &&
340         git stash apply &&
341         case "$(ls -l file)" in *" file -> file2") :;; *) false;; esac
342 '
343
344 test_expect_success SYMLINKS 'stash file to symlink (stage rm)' '
345         git reset --hard &&
346         git rm file &&
347         ln -s file2 file &&
348         git stash save "file to symlink (stage rm)" &&
349         test -f file &&
350         test bar = "$(cat file)" &&
351         git stash apply &&
352         case "$(ls -l file)" in *" file -> file2") :;; *) false;; esac
353 '
354
355 test_expect_success SYMLINKS 'stash file to symlink (full stage)' '
356         git reset --hard &&
357         rm file &&
358         ln -s file2 file &&
359         git add file &&
360         git stash save "file to symlink (full stage)" &&
361         test -f file &&
362         test bar = "$(cat file)" &&
363         git stash apply &&
364         case "$(ls -l file)" in *" file -> file2") :;; *) false;; esac
365 '
366
367 # This test creates a commit with a symlink used for the following tests
368
369 test_expect_success 'stash symlink to file' '
370         git reset --hard &&
371         test_ln_s_add file filelink &&
372         git commit -m "Add symlink" &&
373         rm filelink &&
374         cp file filelink &&
375         git stash save "symlink to file"
376 '
377
378 test_expect_success SYMLINKS 'this must have re-created the symlink' '
379         test -h filelink &&
380         case "$(ls -l filelink)" in *" filelink -> file") :;; *) false;; esac
381 '
382
383 test_expect_success 'unstash must re-create the file' '
384         git stash apply &&
385         ! test -h filelink &&
386         test bar = "$(cat file)"
387 '
388
389 test_expect_success 'stash symlink to file (stage rm)' '
390         git reset --hard &&
391         git rm filelink &&
392         cp file filelink &&
393         git stash save "symlink to file (stage rm)"
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_success 'stash symlink to file (full stage)' '
408         git reset --hard &&
409         rm filelink &&
410         cp file filelink &&
411         git add filelink &&
412         git stash save "symlink to file (full stage)"
413 '
414
415 test_expect_success SYMLINKS 'this must have re-created the symlink' '
416         test -h filelink &&
417         case "$(ls -l filelink)" in *" filelink -> file") :;; *) false;; esac
418 '
419
420 test_expect_success 'unstash must re-create the file' '
421         git stash apply &&
422         ! test -h filelink &&
423         test bar = "$(cat file)"
424 '
425
426 test_expect_failure 'stash directory to file' '
427         git reset --hard &&
428         mkdir dir &&
429         echo foo >dir/file &&
430         git add dir/file &&
431         git commit -m "Add file in dir" &&
432         rm -fr dir &&
433         echo bar >dir &&
434         git stash save "directory to file" &&
435         test -d dir &&
436         test foo = "$(cat dir/file)" &&
437         test_must_fail git stash apply &&
438         test bar = "$(cat dir)" &&
439         git reset --soft HEAD^
440 '
441
442 test_expect_failure 'stash file to directory' '
443         git reset --hard &&
444         rm file &&
445         mkdir file &&
446         echo foo >file/file &&
447         git stash save "file to directory" &&
448         test -f file &&
449         test bar = "$(cat file)" &&
450         git stash apply &&
451         test -f file/file &&
452         test foo = "$(cat file/file)"
453 '
454
455 test_expect_success 'giving too many ref arguments does not modify files' '
456         git stash clear &&
457         test_when_finished "git reset --hard HEAD" &&
458         echo foo >file2 &&
459         git stash &&
460         echo bar >file2 &&
461         git stash &&
462         test-tool chmtime =123456789 file2 &&
463         for type in apply pop "branch stash-branch"
464         do
465                 test_must_fail git stash $type stash@{0} stash@{1} 2>err &&
466                 test_i18ngrep "Too many revisions" err &&
467                 test 123456789 = $(test-tool chmtime -g file2) || return 1
468         done
469 '
470
471 test_expect_success 'drop: too many arguments errors out (does nothing)' '
472         git stash list >expect &&
473         test_must_fail git stash drop stash@{0} stash@{1} 2>err &&
474         test_i18ngrep "Too many revisions" err &&
475         git stash list >actual &&
476         test_cmp expect actual
477 '
478
479 test_expect_success 'show: too many arguments errors out (does nothing)' '
480         test_must_fail git stash show stash@{0} stash@{1} 2>err 1>out &&
481         test_i18ngrep "Too many revisions" err &&
482         test_must_be_empty out
483 '
484
485 test_expect_success 'stash create - no changes' '
486         git stash clear &&
487         test_when_finished "git reset --hard HEAD" &&
488         git reset --hard &&
489         git stash create >actual &&
490         test_must_be_empty actual
491 '
492
493 test_expect_success 'stash branch - no stashes on stack, stash-like argument' '
494         git stash clear &&
495         test_when_finished "git reset --hard HEAD" &&
496         git reset --hard &&
497         echo foo >>file &&
498         STASH_ID=$(git stash create) &&
499         git reset --hard &&
500         git stash branch stash-branch ${STASH_ID} &&
501         test_when_finished "git reset --hard HEAD && git checkout master &&
502         git branch -D stash-branch" &&
503         test $(git ls-files --modified | wc -l) -eq 1
504 '
505
506 test_expect_success 'stash branch - stashes on stack, stash-like argument' '
507         git stash clear &&
508         test_when_finished "git reset --hard HEAD" &&
509         git reset --hard &&
510         echo foo >>file &&
511         git stash &&
512         test_when_finished "git stash drop" &&
513         echo bar >>file &&
514         STASH_ID=$(git stash create) &&
515         git reset --hard &&
516         git stash branch stash-branch ${STASH_ID} &&
517         test_when_finished "git reset --hard HEAD && git checkout master &&
518         git branch -D stash-branch" &&
519         test $(git ls-files --modified | wc -l) -eq 1
520 '
521
522 test_expect_success 'stash branch complains with no arguments' '
523         test_must_fail git stash branch 2>err &&
524         test_i18ngrep "No branch name specified" err
525 '
526
527 test_expect_success 'stash show format defaults to --stat' '
528         git stash clear &&
529         test_when_finished "git reset --hard HEAD" &&
530         git reset --hard &&
531         echo foo >>file &&
532         git stash &&
533         test_when_finished "git stash drop" &&
534         echo bar >>file &&
535         STASH_ID=$(git stash create) &&
536         git reset --hard &&
537         cat >expected <<-EOF &&
538          file | 1 +
539          1 file changed, 1 insertion(+)
540         EOF
541         git stash show ${STASH_ID} >actual &&
542         test_i18ncmp expected actual
543 '
544
545 test_expect_success 'stash show - stashes on stack, stash-like argument' '
546         git stash clear &&
547         test_when_finished "git reset --hard HEAD" &&
548         git reset --hard &&
549         echo foo >>file &&
550         git stash &&
551         test_when_finished "git stash drop" &&
552         echo bar >>file &&
553         STASH_ID=$(git stash create) &&
554         git reset --hard &&
555         echo "1 0       file" >expected &&
556         git stash show --numstat ${STASH_ID} >actual &&
557         test_cmp expected actual
558 '
559
560 test_expect_success 'stash show -p - stashes on stack, stash-like argument' '
561         git stash clear &&
562         test_when_finished "git reset --hard HEAD" &&
563         git reset --hard &&
564         echo foo >>file &&
565         git stash &&
566         test_when_finished "git stash drop" &&
567         echo bar >>file &&
568         STASH_ID=$(git stash create) &&
569         git reset --hard &&
570         cat >expected <<-EOF &&
571         diff --git a/file b/file
572         index 7601807..935fbd3 100644
573         --- a/file
574         +++ b/file
575         @@ -1 +1,2 @@
576          baz
577         +bar
578         EOF
579         git stash show -p ${STASH_ID} >actual &&
580         test_cmp expected actual
581 '
582
583 test_expect_success 'stash show - no stashes on stack, stash-like argument' '
584         git stash clear &&
585         test_when_finished "git reset --hard HEAD" &&
586         git reset --hard &&
587         echo foo >>file &&
588         STASH_ID=$(git stash create) &&
589         git reset --hard &&
590         echo "1 0       file" >expected &&
591         git stash show --numstat ${STASH_ID} >actual &&
592         test_cmp expected actual
593 '
594
595 test_expect_success 'stash show -p - no stashes on stack, stash-like argument' '
596         git stash clear &&
597         test_when_finished "git reset --hard HEAD" &&
598         git reset --hard &&
599         echo foo >>file &&
600         STASH_ID=$(git stash create) &&
601         git reset --hard &&
602         cat >expected <<-EOF &&
603         diff --git a/file b/file
604         index 7601807..71b52c4 100644
605         --- a/file
606         +++ b/file
607         @@ -1 +1,2 @@
608          baz
609         +foo
610         EOF
611         git stash show -p ${STASH_ID} >actual &&
612         test_cmp expected actual
613 '
614
615 test_expect_success 'drop: fail early if specified stash is not a stash ref' '
616         git stash clear &&
617         test_when_finished "git reset --hard HEAD && git stash clear" &&
618         git reset --hard &&
619         echo foo >file &&
620         git stash &&
621         echo bar >file &&
622         git stash &&
623         test_must_fail git stash drop $(git rev-parse stash@{0}) &&
624         git stash pop &&
625         test bar = "$(cat file)" &&
626         git reset --hard HEAD
627 '
628
629 test_expect_success 'pop: fail early if specified stash is not a stash ref' '
630         git stash clear &&
631         test_when_finished "git reset --hard HEAD && git stash clear" &&
632         git reset --hard &&
633         echo foo >file &&
634         git stash &&
635         echo bar >file &&
636         git stash &&
637         test_must_fail git stash pop $(git rev-parse stash@{0}) &&
638         git stash pop &&
639         test bar = "$(cat file)" &&
640         git reset --hard HEAD
641 '
642
643 test_expect_success 'ref with non-existent reflog' '
644         git stash clear &&
645         echo bar5 >file &&
646         echo bar6 >file2 &&
647         git add file2 &&
648         git stash &&
649         test_must_fail git rev-parse --quiet --verify does-not-exist &&
650         test_must_fail git stash drop does-not-exist &&
651         test_must_fail git stash drop does-not-exist@{0} &&
652         test_must_fail git stash pop does-not-exist &&
653         test_must_fail git stash pop does-not-exist@{0} &&
654         test_must_fail git stash apply does-not-exist &&
655         test_must_fail git stash apply does-not-exist@{0} &&
656         test_must_fail git stash show does-not-exist &&
657         test_must_fail git stash show does-not-exist@{0} &&
658         test_must_fail git stash branch tmp does-not-exist &&
659         test_must_fail git stash branch tmp does-not-exist@{0} &&
660         git stash drop
661 '
662
663 test_expect_success 'invalid ref of the form stash@{n}, n >= N' '
664         git stash clear &&
665         test_must_fail git stash drop stash@{0} &&
666         echo bar5 >file &&
667         echo bar6 >file2 &&
668         git add file2 &&
669         git stash &&
670         test_must_fail git stash drop stash@{1} &&
671         test_must_fail git stash pop stash@{1} &&
672         test_must_fail git stash apply stash@{1} &&
673         test_must_fail git stash show stash@{1} &&
674         test_must_fail git stash branch tmp stash@{1} &&
675         git stash drop
676 '
677
678 test_expect_success 'invalid ref of the form "n", n >= N' '
679         git stash clear &&
680         test_must_fail git stash drop 0 &&
681         echo bar5 >file &&
682         echo bar6 >file2 &&
683         git add file2 &&
684         git stash &&
685         test_must_fail git stash drop 1 &&
686         test_must_fail git stash pop 1 &&
687         test_must_fail git stash apply 1 &&
688         test_must_fail git stash show 1 &&
689         test_must_fail git stash branch tmp 1 &&
690         git stash drop
691 '
692
693 test_expect_success 'branch: do not drop the stash if the branch exists' '
694         git stash clear &&
695         echo foo >file &&
696         git add file &&
697         git commit -m initial &&
698         echo bar >file &&
699         git stash &&
700         test_must_fail git stash branch master stash@{0} &&
701         git rev-parse stash@{0} --
702 '
703
704 test_expect_success 'branch: should not drop the stash if the apply fails' '
705         git stash clear &&
706         git reset HEAD~1 --hard &&
707         echo foo >file &&
708         git add file &&
709         git commit -m initial &&
710         echo bar >file &&
711         git stash &&
712         echo baz >file &&
713         test_when_finished "git checkout master" &&
714         test_must_fail git stash branch new_branch stash@{0} &&
715         git rev-parse stash@{0} --
716 '
717
718 test_expect_success 'apply: show same status as git status (relative to ./)' '
719         git stash clear &&
720         echo 1 >subdir/subfile1 &&
721         echo 2 >subdir/subfile2 &&
722         git add subdir/subfile1 &&
723         git commit -m subdir &&
724         (
725                 cd subdir &&
726                 echo x >subfile1 &&
727                 echo x >../file &&
728                 git status >../expect &&
729                 git stash &&
730                 sane_unset GIT_MERGE_VERBOSITY &&
731                 git stash apply
732         ) |
733         sed -e 1d >actual && # drop "Saved..."
734         test_i18ncmp expect actual
735 '
736
737 cat >expect <<EOF
738 diff --git a/HEAD b/HEAD
739 new file mode 100644
740 index 0000000..fe0cbee
741 --- /dev/null
742 +++ b/HEAD
743 @@ -0,0 +1 @@
744 +file-not-a-ref
745 EOF
746
747 test_expect_success 'stash where working directory contains "HEAD" file' '
748         git stash clear &&
749         git reset --hard &&
750         echo file-not-a-ref >HEAD &&
751         git add HEAD &&
752         test_tick &&
753         git stash &&
754         git diff-files --quiet &&
755         git diff-index --cached --quiet HEAD &&
756         test "$(git rev-parse stash^)" = "$(git rev-parse HEAD)" &&
757         git diff stash^..stash >output &&
758         test_cmp expect output
759 '
760
761 test_expect_success 'store called with invalid commit' '
762         test_must_fail git stash store foo
763 '
764
765 test_expect_success 'store updates stash ref and reflog' '
766         git stash clear &&
767         git reset --hard &&
768         echo quux >bazzy &&
769         git add bazzy &&
770         STASH_ID=$(git stash create) &&
771         git reset --hard &&
772         test_path_is_missing bazzy &&
773         git stash store -m quuxery $STASH_ID &&
774         test $(git rev-parse stash) = $STASH_ID &&
775         git reflog --format=%H stash| grep $STASH_ID &&
776         git stash pop &&
777         grep quux bazzy
778 '
779
780 test_expect_success 'handle stash specification with spaces' '
781         git stash clear &&
782         echo pig >file &&
783         git stash &&
784         stamp=$(git log -g --format="%cd" -1 refs/stash) &&
785         test_tick &&
786         echo cow >file &&
787         git stash &&
788         git stash apply "stash@{$stamp}" &&
789         grep pig file
790 '
791
792 test_expect_success 'setup stash with index and worktree changes' '
793         git stash clear &&
794         git reset --hard &&
795         echo index >file &&
796         git add file &&
797         echo working >file &&
798         git stash
799 '
800
801 test_expect_success 'stash list implies --first-parent -m' '
802         cat >expect <<-EOF &&
803         stash@{0}
804
805         diff --git a/file b/file
806         index 257cc56..d26b33d 100644
807         --- a/file
808         +++ b/file
809         @@ -1 +1 @@
810         -foo
811         +working
812         EOF
813         git stash list --format=%gd -p >actual &&
814         test_cmp expect actual
815 '
816
817 test_expect_success 'stash list --cc shows combined diff' '
818         cat >expect <<-\EOF &&
819         stash@{0}
820
821         diff --cc file
822         index 257cc56,9015a7a..d26b33d
823         --- a/file
824         +++ b/file
825         @@@ -1,1 -1,1 +1,1 @@@
826         - foo
827          -index
828         ++working
829         EOF
830         git stash list --format=%gd -p --cc >actual &&
831         test_cmp expect actual
832 '
833
834 test_expect_success 'stash is not confused by partial renames' '
835         mv file renamed &&
836         git add renamed &&
837         git stash &&
838         git stash apply &&
839         test_path_is_file renamed &&
840         test_path_is_missing file
841 '
842
843 test_expect_success 'push -m shows right message' '
844         >foo &&
845         git add foo &&
846         git stash push -m "test message" &&
847         echo "stash@{0}: On master: test message" >expect &&
848         git stash list -1 >actual &&
849         test_cmp expect actual
850 '
851
852 test_expect_success 'push -m also works without space' '
853         >foo &&
854         git add foo &&
855         git stash push -m"unspaced test message" &&
856         echo "stash@{0}: On master: unspaced test message" >expect &&
857         git stash list -1 >actual &&
858         test_cmp expect actual
859 '
860
861 test_expect_success 'store -m foo shows right message' '
862         git stash clear &&
863         git reset --hard &&
864         echo quux >bazzy &&
865         git add bazzy &&
866         STASH_ID=$(git stash create) &&
867         git stash store -m "store m" $STASH_ID &&
868         echo "stash@{0}: store m" >expect &&
869         git stash list -1 >actual &&
870         test_cmp expect actual
871 '
872
873 test_expect_success 'store -mfoo shows right message' '
874         git stash clear &&
875         git reset --hard &&
876         echo quux >bazzy &&
877         git add bazzy &&
878         STASH_ID=$(git stash create) &&
879         git stash store -m"store mfoo" $STASH_ID &&
880         echo "stash@{0}: store mfoo" >expect &&
881         git stash list -1 >actual &&
882         test_cmp expect actual
883 '
884
885 test_expect_success 'store --message=foo shows right message' '
886         git stash clear &&
887         git reset --hard &&
888         echo quux >bazzy &&
889         git add bazzy &&
890         STASH_ID=$(git stash create) &&
891         git stash store --message="store message=foo" $STASH_ID &&
892         echo "stash@{0}: store message=foo" >expect &&
893         git stash list -1 >actual &&
894         test_cmp expect actual
895 '
896
897 test_expect_success 'store --message foo shows right message' '
898         git stash clear &&
899         git reset --hard &&
900         echo quux >bazzy &&
901         git add bazzy &&
902         STASH_ID=$(git stash create) &&
903         git stash store --message "store message foo" $STASH_ID &&
904         echo "stash@{0}: store message foo" >expect &&
905         git stash list -1 >actual &&
906         test_cmp expect actual
907 '
908
909 test_expect_success 'push -mfoo uses right message' '
910         >foo &&
911         git add foo &&
912         git stash push -m"test mfoo" &&
913         echo "stash@{0}: On master: test mfoo" >expect &&
914         git stash list -1 >actual &&
915         test_cmp expect actual
916 '
917
918 test_expect_success 'push --message foo is synonym for -mfoo' '
919         >foo &&
920         git add foo &&
921         git stash push --message "test message foo" &&
922         echo "stash@{0}: On master: test message foo" >expect &&
923         git stash list -1 >actual &&
924         test_cmp expect actual
925 '
926
927 test_expect_success 'push --message=foo is synonym for -mfoo' '
928         >foo &&
929         git add foo &&
930         git stash push --message="test message=foo" &&
931         echo "stash@{0}: On master: test message=foo" >expect &&
932         git stash list -1 >actual &&
933         test_cmp expect actual
934 '
935
936 test_expect_success 'push -m shows right message' '
937         >foo &&
938         git add foo &&
939         git stash push -m "test m foo" &&
940         echo "stash@{0}: On master: test m foo" >expect &&
941         git stash list -1 >actual &&
942         test_cmp expect actual
943 '
944
945 test_expect_success 'create stores correct message' '
946         >foo &&
947         git add foo &&
948         STASH_ID=$(git stash create "create test message") &&
949         echo "On master: create test message" >expect &&
950         git show --pretty=%s -s ${STASH_ID} >actual &&
951         test_cmp expect actual
952 '
953
954 test_expect_success 'create with multiple arguments for the message' '
955         >foo &&
956         git add foo &&
957         STASH_ID=$(git stash create test untracked) &&
958         echo "On master: test untracked" >expect &&
959         git show --pretty=%s -s ${STASH_ID} >actual &&
960         test_cmp expect actual
961 '
962
963 test_expect_success 'create in a detached state' '
964         test_when_finished "git checkout master" &&
965         git checkout HEAD~1 &&
966         >foo &&
967         git add foo &&
968         STASH_ID=$(git stash create) &&
969         HEAD_ID=$(git rev-parse --short HEAD) &&
970         echo "WIP on (no branch): ${HEAD_ID} initial" >expect &&
971         git show --pretty=%s -s ${STASH_ID} >actual &&
972         test_cmp expect actual
973 '
974
975 test_expect_success 'stash -- <pathspec> stashes and restores the file' '
976         >foo &&
977         >bar &&
978         git add foo bar &&
979         git stash push -- foo &&
980         test_path_is_file bar &&
981         test_path_is_missing foo &&
982         git stash pop &&
983         test_path_is_file foo &&
984         test_path_is_file bar
985 '
986
987 test_expect_success 'stash -- <pathspec> stashes in subdirectory' '
988         mkdir sub &&
989         >foo &&
990         >bar &&
991         git add foo bar &&
992         (
993                 cd sub &&
994                 git stash push -- ../foo
995         ) &&
996         test_path_is_file bar &&
997         test_path_is_missing foo &&
998         git stash pop &&
999         test_path_is_file foo &&
1000         test_path_is_file bar
1001 '
1002
1003 test_expect_success 'stash with multiple pathspec arguments' '
1004         >foo &&
1005         >bar &&
1006         >extra &&
1007         git add foo bar extra &&
1008         git stash push -- foo bar &&
1009         test_path_is_missing bar &&
1010         test_path_is_missing foo &&
1011         test_path_is_file extra &&
1012         git stash pop &&
1013         test_path_is_file foo &&
1014         test_path_is_file bar &&
1015         test_path_is_file extra
1016 '
1017
1018 test_expect_success 'stash with file including $IFS character' '
1019         >"foo bar" &&
1020         >foo &&
1021         >bar &&
1022         git add foo* &&
1023         git stash push -- "foo b*" &&
1024         test_path_is_missing "foo bar" &&
1025         test_path_is_file foo &&
1026         test_path_is_file bar &&
1027         git stash pop &&
1028         test_path_is_file "foo bar" &&
1029         test_path_is_file foo &&
1030         test_path_is_file bar
1031 '
1032
1033 test_expect_success 'stash with pathspec matching multiple paths' '
1034        echo original >file &&
1035        echo original >other-file &&
1036        git commit -m "two" file other-file &&
1037        echo modified >file &&
1038        echo modified >other-file &&
1039        git stash push -- "*file" &&
1040        echo original >expect &&
1041        test_cmp expect file &&
1042        test_cmp expect other-file &&
1043        git stash pop &&
1044        echo modified >expect &&
1045        test_cmp expect file &&
1046        test_cmp expect other-file
1047 '
1048
1049 test_expect_success 'stash push -p with pathspec shows no changes only once' '
1050         >foo &&
1051         git add foo &&
1052         git commit -m "tmp" &&
1053         git stash push -p foo >actual &&
1054         echo "No local changes to save" >expect &&
1055         git reset --hard HEAD~ &&
1056         test_i18ncmp expect actual
1057 '
1058
1059 test_expect_success 'push <pathspec>: show no changes when there are none' '
1060         >foo &&
1061         git add foo &&
1062         git commit -m "tmp" &&
1063         git stash push foo >actual &&
1064         echo "No local changes to save" >expect &&
1065         git reset --hard HEAD~ &&
1066         test_i18ncmp expect actual
1067 '
1068
1069 test_expect_success 'push: <pathspec> not in the repository errors out' '
1070         >untracked &&
1071         test_must_fail git stash push untracked &&
1072         test_path_is_file untracked
1073 '
1074
1075 test_expect_success 'untracked files are left in place when -u is not given' '
1076         >file &&
1077         git add file &&
1078         >untracked &&
1079         git stash push file &&
1080         test_path_is_file untracked
1081 '
1082
1083 test_expect_success 'stash without verb with pathspec' '
1084         >"foo bar" &&
1085         >foo &&
1086         >bar &&
1087         git add foo* &&
1088         git stash -- "foo b*" &&
1089         test_path_is_missing "foo bar" &&
1090         test_path_is_file foo &&
1091         test_path_is_file bar &&
1092         git stash pop &&
1093         test_path_is_file "foo bar" &&
1094         test_path_is_file foo &&
1095         test_path_is_file bar
1096 '
1097
1098 test_expect_success 'stash -k -- <pathspec> leaves unstaged files intact' '
1099         git reset &&
1100         >foo &&
1101         >bar &&
1102         git add foo bar &&
1103         git commit -m "test" &&
1104         echo "foo" >foo &&
1105         echo "bar" >bar &&
1106         git stash -k -- foo &&
1107         test "",bar = $(cat foo),$(cat bar) &&
1108         git stash pop &&
1109         test foo,bar = $(cat foo),$(cat bar)
1110 '
1111
1112 test_expect_success 'stash -- <subdir> leaves untracked files in subdir intact' '
1113         git reset &&
1114         >subdir/untracked &&
1115         >subdir/tracked1 &&
1116         >subdir/tracked2 &&
1117         git add subdir/tracked* &&
1118         git stash -- subdir/ &&
1119         test_path_is_missing subdir/tracked1 &&
1120         test_path_is_missing subdir/tracked2 &&
1121         test_path_is_file subdir/untracked &&
1122         git stash pop &&
1123         test_path_is_file subdir/tracked1 &&
1124         test_path_is_file subdir/tracked2 &&
1125         test_path_is_file subdir/untracked
1126 '
1127
1128 test_expect_success 'stash -- <subdir> works with binary files' '
1129         git reset &&
1130         >subdir/untracked &&
1131         >subdir/tracked &&
1132         cp "$TEST_DIRECTORY"/test-binary-1.png subdir/tracked-binary &&
1133         git add subdir/tracked* &&
1134         git stash -- subdir/ &&
1135         test_path_is_missing subdir/tracked &&
1136         test_path_is_missing subdir/tracked-binary &&
1137         test_path_is_file subdir/untracked &&
1138         git stash pop &&
1139         test_path_is_file subdir/tracked &&
1140         test_path_is_file subdir/tracked-binary &&
1141         test_path_is_file subdir/untracked
1142 '
1143
1144 test_expect_success 'stash with user.name and user.email set works' '
1145         test_config user.name "A U Thor" &&
1146         test_config user.email "a.u@thor" &&
1147         git stash
1148 '
1149
1150 test_expect_success 'stash works when user.name and user.email are not set' '
1151         git reset &&
1152         >1 &&
1153         git add 1 &&
1154         echo "$GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>" >expect &&
1155         git stash &&
1156         git show -s --format="%an <%ae>" refs/stash >actual &&
1157         test_cmp expect actual &&
1158         >2 &&
1159         git add 2 &&
1160         test_config user.useconfigonly true &&
1161         test_config stash.usebuiltin true &&
1162         (
1163                 sane_unset GIT_AUTHOR_NAME &&
1164                 sane_unset GIT_AUTHOR_EMAIL &&
1165                 sane_unset GIT_COMMITTER_NAME &&
1166                 sane_unset GIT_COMMITTER_EMAIL &&
1167                 test_unconfig user.email &&
1168                 test_unconfig user.name &&
1169                 test_must_fail git commit -m "should fail" &&
1170                 echo "git stash <git@stash>" >expect &&
1171                 >2 &&
1172                 git stash &&
1173                 git show -s --format="%an <%ae>" refs/stash >actual &&
1174                 test_cmp expect actual
1175         )
1176 '
1177
1178 test_done