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