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