t1502 (rev-parse --parseopt): test exit code from "-h"
[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         test_tick &&
14         git commit -m initial &&
15         echo 2 > file &&
16         git add file &&
17         echo 3 > file &&
18         test_tick &&
19         git stash &&
20         git diff-files --quiet &&
21         git diff-index --cached --quiet HEAD
22 '
23
24 cat > expect << EOF
25 diff --git a/file b/file
26 index 0cfbf08..00750ed 100644
27 --- a/file
28 +++ b/file
29 @@ -1 +1 @@
30 -2
31 +3
32 EOF
33
34 test_expect_success 'parents of stash' '
35         test $(git rev-parse stash^) = $(git rev-parse HEAD) &&
36         git diff stash^2..stash > output &&
37         test_cmp output expect
38 '
39
40 test_expect_success 'apply needs clean working directory' '
41         echo 4 > other-file &&
42         git add other-file &&
43         echo 5 > other-file &&
44         test_must_fail git stash apply
45 '
46
47 test_expect_success 'apply stashed changes' '
48         git add other-file &&
49         test_tick &&
50         git commit -m other-file &&
51         git stash apply &&
52         test 3 = $(cat file) &&
53         test 1 = $(git show :file) &&
54         test 1 = $(git show HEAD:file)
55 '
56
57 test_expect_success 'apply stashed changes (including index)' '
58         git reset --hard HEAD^ &&
59         echo 6 > other-file &&
60         git add other-file &&
61         test_tick &&
62         git commit -m other-file &&
63         git stash apply --index &&
64         test 3 = $(cat file) &&
65         test 2 = $(git show :file) &&
66         test 1 = $(git show HEAD:file)
67 '
68
69 test_expect_success 'unstashing in a subdirectory' '
70         git reset --hard HEAD &&
71         mkdir subdir &&
72         (
73                 cd subdir &&
74                 git stash apply
75         )
76 '
77
78 test_expect_success 'drop top stash' '
79         git reset --hard &&
80         git stash list > stashlist1 &&
81         echo 7 > file &&
82         git stash &&
83         git stash drop &&
84         git stash list > stashlist2 &&
85         test_cmp stashlist1 stashlist2 &&
86         git stash apply &&
87         test 3 = $(cat file) &&
88         test 1 = $(git show :file) &&
89         test 1 = $(git show HEAD:file)
90 '
91
92 test_expect_success 'drop middle stash' '
93         git reset --hard &&
94         echo 8 > file &&
95         git stash &&
96         echo 9 > file &&
97         git stash &&
98         git stash drop stash@{1} &&
99         test 2 = $(git stash list | wc -l) &&
100         git stash apply &&
101         test 9 = $(cat file) &&
102         test 1 = $(git show :file) &&
103         test 1 = $(git show HEAD:file) &&
104         git reset --hard &&
105         git stash drop &&
106         git stash apply &&
107         test 3 = $(cat file) &&
108         test 1 = $(git show :file) &&
109         test 1 = $(git show HEAD:file)
110 '
111
112 test_expect_success 'stash pop' '
113         git reset --hard &&
114         git stash pop &&
115         test 3 = $(cat file) &&
116         test 1 = $(git show :file) &&
117         test 1 = $(git show HEAD:file) &&
118         test 0 = $(git stash list | wc -l)
119 '
120
121 cat > expect << EOF
122 diff --git a/file2 b/file2
123 new file mode 100644
124 index 0000000..1fe912c
125 --- /dev/null
126 +++ b/file2
127 @@ -0,0 +1 @@
128 +bar2
129 EOF
130
131 cat > expect1 << EOF
132 diff --git a/file b/file
133 index 257cc56..5716ca5 100644
134 --- a/file
135 +++ b/file
136 @@ -1 +1 @@
137 -foo
138 +bar
139 EOF
140
141 cat > expect2 << EOF
142 diff --git a/file b/file
143 index 7601807..5716ca5 100644
144 --- a/file
145 +++ b/file
146 @@ -1 +1 @@
147 -baz
148 +bar
149 diff --git a/file2 b/file2
150 new file mode 100644
151 index 0000000..1fe912c
152 --- /dev/null
153 +++ b/file2
154 @@ -0,0 +1 @@
155 +bar2
156 EOF
157
158 test_expect_success 'stash branch' '
159         echo foo > file &&
160         git commit file -m first &&
161         echo bar > file &&
162         echo bar2 > file2 &&
163         git add file2 &&
164         git stash &&
165         echo baz > file &&
166         git commit file -m second &&
167         git stash branch stashbranch &&
168         test refs/heads/stashbranch = $(git symbolic-ref HEAD) &&
169         test $(git rev-parse HEAD) = $(git rev-parse master^) &&
170         git diff --cached > output &&
171         test_cmp output expect &&
172         git diff > output &&
173         test_cmp output expect1 &&
174         git add file &&
175         git commit -m alternate\ second &&
176         git diff master..stashbranch > output &&
177         test_cmp output expect2 &&
178         test 0 = $(git stash list | wc -l)
179 '
180
181 test_expect_success 'apply -q is quiet' '
182         echo foo > file &&
183         git stash &&
184         git stash apply -q > output.out 2>&1 &&
185         test ! -s output.out
186 '
187
188 test_expect_success 'save -q is quiet' '
189         git stash save --quiet > output.out 2>&1 &&
190         test ! -s output.out
191 '
192
193 test_expect_success 'pop -q is quiet' '
194         git stash pop -q > output.out 2>&1 &&
195         test ! -s output.out
196 '
197
198 test_expect_success 'pop -q --index works and is quiet' '
199         echo foo > file &&
200         git add file &&
201         git stash save --quiet &&
202         git stash pop -q --index > output.out 2>&1 &&
203         test foo = "$(git show :file)" &&
204         test ! -s output.out
205 '
206
207 test_expect_success 'drop -q is quiet' '
208         git stash &&
209         git stash drop -q > output.out 2>&1 &&
210         test ! -s output.out
211 '
212
213 test_expect_success 'stash -k' '
214         echo bar3 > file &&
215         echo bar4 > file2 &&
216         git add file2 &&
217         git stash -k &&
218         test bar,bar4 = $(cat file),$(cat file2)
219 '
220
221 test_expect_success 'stash --invalid-option' '
222         echo bar5 > file &&
223         echo bar6 > file2 &&
224         git add file2 &&
225         test_must_fail git stash --invalid-option &&
226         test_must_fail git stash save --invalid-option &&
227         test bar5,bar6 = $(cat file),$(cat file2) &&
228         git stash -- -message-starting-with-dash &&
229         test bar,bar2 = $(cat file),$(cat file2)
230 '
231
232 test_expect_success 'stash an added file' '
233         git reset --hard &&
234         echo new >file3 &&
235         git add file3 &&
236         git stash save "added file" &&
237         ! test -r file3 &&
238         git stash apply &&
239         test new = "$(cat file3)"
240 '
241
242 test_expect_success 'stash rm then recreate' '
243         git reset --hard &&
244         git rm file &&
245         echo bar7 >file &&
246         git stash save "rm then recreate" &&
247         test bar = "$(cat file)" &&
248         git stash apply &&
249         test bar7 = "$(cat file)"
250 '
251
252 test_expect_success 'stash rm and ignore' '
253         git reset --hard &&
254         git rm file &&
255         echo file >.gitignore &&
256         git stash save "rm and ignore" &&
257         test bar = "$(cat file)" &&
258         test file = "$(cat .gitignore)" &&
259         git stash apply &&
260         ! test -r file &&
261         test file = "$(cat .gitignore)"
262 '
263
264 test_expect_success 'stash rm and ignore (stage .gitignore)' '
265         git reset --hard &&
266         git rm file &&
267         echo file >.gitignore &&
268         git add .gitignore &&
269         git stash save "rm and ignore (stage .gitignore)" &&
270         test bar = "$(cat file)" &&
271         ! test -r .gitignore &&
272         git stash apply &&
273         ! test -r file &&
274         test file = "$(cat .gitignore)"
275 '
276
277 test_expect_success SYMLINKS 'stash file to symlink' '
278         git reset --hard &&
279         rm file &&
280         ln -s file2 file &&
281         git stash save "file to symlink" &&
282         test -f file &&
283         test bar = "$(cat file)" &&
284         git stash apply &&
285         case "$(ls -l file)" in *" file -> file2") :;; *) false;; esac
286 '
287
288 test_expect_success SYMLINKS 'stash file to symlink (stage rm)' '
289         git reset --hard &&
290         git rm file &&
291         ln -s file2 file &&
292         git stash save "file to symlink (stage rm)" &&
293         test -f file &&
294         test bar = "$(cat file)" &&
295         git stash apply &&
296         case "$(ls -l file)" in *" file -> file2") :;; *) false;; esac
297 '
298
299 test_expect_success SYMLINKS 'stash file to symlink (full stage)' '
300         git reset --hard &&
301         rm file &&
302         ln -s file2 file &&
303         git add file &&
304         git stash save "file to symlink (full stage)" &&
305         test -f file &&
306         test bar = "$(cat file)" &&
307         git stash apply &&
308         case "$(ls -l file)" in *" file -> file2") :;; *) false;; esac
309 '
310
311 # This test creates a commit with a symlink used for the following tests
312
313 test_expect_success SYMLINKS 'stash symlink to file' '
314         git reset --hard &&
315         ln -s file filelink &&
316         git add filelink &&
317         git commit -m "Add symlink" &&
318         rm filelink &&
319         cp file filelink &&
320         git stash save "symlink to file" &&
321         test -h filelink &&
322         case "$(ls -l filelink)" in *" filelink -> file") :;; *) false;; esac &&
323         git stash apply &&
324         ! test -h filelink &&
325         test bar = "$(cat file)"
326 '
327
328 test_expect_success SYMLINKS 'stash symlink to file (stage rm)' '
329         git reset --hard &&
330         git rm filelink &&
331         cp file filelink &&
332         git stash save "symlink to file (stage rm)" &&
333         test -h filelink &&
334         case "$(ls -l filelink)" in *" filelink -> file") :;; *) false;; esac &&
335         git stash apply &&
336         ! test -h filelink &&
337         test bar = "$(cat file)"
338 '
339
340 test_expect_success SYMLINKS 'stash symlink to file (full stage)' '
341         git reset --hard &&
342         rm filelink &&
343         cp file filelink &&
344         git add filelink &&
345         git stash save "symlink to file (full stage)" &&
346         test -h filelink &&
347         case "$(ls -l filelink)" in *" filelink -> file") :;; *) false;; esac &&
348         git stash apply &&
349         ! test -h filelink &&
350         test bar = "$(cat file)"
351 '
352
353 test_expect_failure 'stash directory to file' '
354         git reset --hard &&
355         mkdir dir &&
356         echo foo >dir/file &&
357         git add dir/file &&
358         git commit -m "Add file in dir" &&
359         rm -fr dir &&
360         echo bar >dir &&
361         git stash save "directory to file" &&
362         test -d dir &&
363         test foo = "$(cat dir/file)" &&
364         test_must_fail git stash apply &&
365         test bar = "$(cat dir)" &&
366         git reset --soft HEAD^
367 '
368
369 test_expect_failure 'stash file to directory' '
370         git reset --hard &&
371         rm file &&
372         mkdir file &&
373         echo foo >file/file &&
374         git stash save "file to directory" &&
375         test -f file &&
376         test bar = "$(cat file)" &&
377         git stash apply &&
378         test -f file/file &&
379         test foo = "$(cat file/file)"
380 '
381
382 test_expect_success 'stash branch - no stashes on stack, stash-like argument' '
383         git stash clear &&
384         test_when_finished "git reset --hard HEAD" &&
385         git reset --hard &&
386         echo foo >> file &&
387         STASH_ID=$(git stash create) &&
388         git reset --hard &&
389         git stash branch stash-branch ${STASH_ID} &&
390         test_when_finished "git reset --hard HEAD && git checkout master && git branch -D stash-branch" &&
391         test $(git ls-files --modified | wc -l) -eq 1
392 '
393
394 test_expect_success 'stash branch - stashes on stack, stash-like argument' '
395         git stash clear &&
396         test_when_finished "git reset --hard HEAD" &&
397         git reset --hard &&
398         echo foo >> file &&
399         git stash &&
400         test_when_finished "git stash drop" &&
401         echo bar >> file &&
402         STASH_ID=$(git stash create) &&
403         git reset --hard &&
404         git stash branch stash-branch ${STASH_ID} &&
405         test_when_finished "git reset --hard HEAD && git checkout master && git branch -D stash-branch" &&
406         test $(git ls-files --modified | wc -l) -eq 1
407 '
408
409 test_expect_success 'stash show - stashes on stack, stash-like argument' '
410         git stash clear &&
411         test_when_finished "git reset --hard HEAD" &&
412         git reset --hard &&
413         echo foo >> file &&
414         git stash &&
415         test_when_finished "git stash drop" &&
416         echo bar >> file &&
417         STASH_ID=$(git stash create) &&
418         git reset --hard &&
419         cat >expected <<-EOF &&
420          file |    1 +
421          1 files changed, 1 insertions(+), 0 deletions(-)
422         EOF
423         git stash show ${STASH_ID} >actual &&
424         test_cmp expected actual
425 '
426
427 test_expect_success 'stash show -p - stashes on stack, stash-like argument' '
428         git stash clear &&
429         test_when_finished "git reset --hard HEAD" &&
430         git reset --hard &&
431         echo foo >> file &&
432         git stash &&
433         test_when_finished "git stash drop" &&
434         echo bar >> file &&
435         STASH_ID=$(git stash create) &&
436         git reset --hard &&
437         cat >expected <<-EOF &&
438         diff --git a/file b/file
439         index 7601807..935fbd3 100644
440         --- a/file
441         +++ b/file
442         @@ -1 +1,2 @@
443          baz
444         +bar
445         EOF
446         git stash show -p ${STASH_ID} >actual &&
447         test_cmp expected actual
448 '
449
450 test_expect_success 'stash show - no stashes on stack, stash-like argument' '
451         git stash clear &&
452         test_when_finished "git reset --hard HEAD" &&
453         git reset --hard &&
454         echo foo >> file &&
455         STASH_ID=$(git stash create) &&
456         git reset --hard &&
457         cat >expected <<-EOF &&
458          file |    1 +
459          1 files changed, 1 insertions(+), 0 deletions(-)
460         EOF
461         git stash show ${STASH_ID} >actual &&
462         test_cmp expected actual
463 '
464
465 test_expect_success 'stash show -p - no stashes on stack, stash-like argument' '
466         git stash clear &&
467         test_when_finished "git reset --hard HEAD" &&
468         git reset --hard &&
469         echo foo >> file &&
470         STASH_ID=$(git stash create) &&
471         git reset --hard &&
472         cat >expected <<-EOF &&
473         diff --git a/file b/file
474         index 7601807..71b52c4 100644
475         --- a/file
476         +++ b/file
477         @@ -1 +1,2 @@
478          baz
479         +foo
480         EOF
481         git stash show -p ${STASH_ID} >actual &&
482         test_cmp expected actual
483 '
484
485 test_expect_success 'stash drop - fail early if specified stash is not a stash reference' '
486         git stash clear &&
487         test_when_finished "git reset --hard HEAD && git stash clear" &&
488         git reset --hard &&
489         echo foo > file &&
490         git stash &&
491         echo bar > file &&
492         git stash &&
493         test_must_fail git stash drop $(git rev-parse stash@{0}) &&
494         git stash pop &&
495         test bar = "$(cat file)" &&
496         git reset --hard HEAD
497 '
498
499 test_expect_success 'stash pop - fail early if specified stash is not a stash reference' '
500         git stash clear &&
501         test_when_finished "git reset --hard HEAD && git stash clear" &&
502         git reset --hard &&
503         echo foo > file &&
504         git stash &&
505         echo bar > file &&
506         git stash &&
507         test_must_fail git stash pop $(git rev-parse stash@{0}) &&
508         git stash pop &&
509         test bar = "$(cat file)" &&
510         git reset --hard HEAD
511 '
512
513 test_expect_success 'ref with non-existant reflog' '
514         git stash clear &&
515         echo bar5 > file &&
516         echo bar6 > file2 &&
517         git add file2 &&
518         git stash &&
519         ! "git rev-parse --quiet --verify does-not-exist" &&
520         test_must_fail git stash drop does-not-exist &&
521         test_must_fail git stash drop does-not-exist@{0} &&
522         test_must_fail git stash pop does-not-exist &&
523         test_must_fail git stash pop does-not-exist@{0} &&
524         test_must_fail git stash apply does-not-exist &&
525         test_must_fail git stash apply does-not-exist@{0} &&
526         test_must_fail git stash show does-not-exist &&
527         test_must_fail git stash show does-not-exist@{0} &&
528         test_must_fail git stash branch tmp does-not-exist &&
529         test_must_fail git stash branch tmp does-not-exist@{0} &&
530         git stash drop
531 '
532
533 test_expect_success 'invalid ref of the form stash@{n}, n >= N' '
534         git stash clear &&
535         test_must_fail git stash drop stash@{0} &&
536         echo bar5 > file &&
537         echo bar6 > file2 &&
538         git add file2 &&
539         git stash &&
540         test_must_fail git drop stash@{1} &&
541         test_must_fail git pop stash@{1} &&
542         test_must_fail git apply stash@{1} &&
543         test_must_fail git show stash@{1} &&
544         test_must_fail git branch tmp stash@{1} &&
545         git stash drop
546 '
547
548 test_expect_success 'stash branch should not drop the stash if the branch exists' '
549         git stash clear &&
550         echo foo >file &&
551         git add file &&
552         git commit -m initial &&
553         echo bar >file &&
554         git stash &&
555         test_must_fail git stash branch master stash@{0} &&
556         git rev-parse stash@{0} --
557 '
558
559 test_done