stash: fix accidental apply of non-existent stashes
[git/jnareb-git.git] / t / t3903-stash.sh
blob4f4825770f179939f9676ea970bc86c4da0ab0e0
1 #!/bin/sh
3 # Copyright (c) 2007 Johannes E Schindelin
6 test_description='Test git stash'
8 . ./test-lib.sh
10 test_expect_success 'stash some dirty working directory' '
11 echo 1 > file &&
12 git add file &&
13 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
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 @@
32 EOF
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
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
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
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)
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)
75 test_expect_success 'unstashing in a subdirectory' '
76 git reset --hard HEAD &&
77 mkdir subdir &&
79 cd subdir &&
80 git stash apply
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)
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)
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)
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
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
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
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)
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
194 test_expect_success 'save -q is quiet' '
195 git stash save --quiet > output.out 2>&1 &&
196 test ! -s output.out
199 test_expect_success 'pop -q is quiet' '
200 git stash pop -q > output.out 2>&1 &&
201 test ! -s output.out
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
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
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)
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)
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)"
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)"
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)"
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)"
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
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
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
317 # This test creates a commit with a symlink used for the following tests
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)"
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)"
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)"
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^
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)"
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
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
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(-)
429 git stash show ${STASH_ID} >actual &&
430 test_cmp expected actual
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 @@
450 +bar
452 git stash show -p ${STASH_ID} >actual &&
453 test_cmp expected actual
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(-)
467 git stash show ${STASH_ID} >actual &&
468 test_cmp expected actual
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 @@
485 +foo
487 git stash show -p ${STASH_ID} >actual &&
488 test_cmp expected actual
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
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
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
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 drop stash@{1} &&
547 test_must_fail git pop stash@{1} &&
548 test_must_fail git apply stash@{1} &&
549 test_must_fail git show stash@{1} &&
550 test_must_fail git branch tmp stash@{1} &&
551 git stash drop
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} --
565 test_done