t / t3903-stash.shon commit Documentation/git-bisect.txt: git bisect term → git bisect terms (bbd374d)
   1#!/bin/sh
   2#
   3# Copyright (c) 2007 Johannes E Schindelin
   4#
   5
   6test_description='Test git stash'
   7
   8. ./test-lib.sh
   9
  10test_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
  26cat > expect << EOF
  27diff --git a/file b/file
  28index 0cfbf08..00750ed 100644
  29--- a/file
  30+++ b/file
  31@@ -1 +1 @@
  32-2
  33+3
  34EOF
  35
  36test_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 output expect
  40'
  41
  42test_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
  48test_expect_success 'apply requires a clean index' '
  49        test_when_finished "git reset --hard" &&
  50        echo changed >other-file &&
  51        git add other-file &&
  52        test_must_fail git stash apply
  53'
  54
  55test_expect_success 'apply does not need clean working directory' '
  56        echo 4 >other-file &&
  57        git stash apply &&
  58        echo 3 >expect &&
  59        test_cmp expect file
  60'
  61
  62test_expect_success 'apply does not clobber working directory changes' '
  63        git reset --hard &&
  64        echo 4 >file &&
  65        test_must_fail git stash apply &&
  66        echo 4 >expect &&
  67        test_cmp expect file
  68'
  69
  70test_expect_success 'apply stashed changes' '
  71        git reset --hard &&
  72        echo 5 >other-file &&
  73        git add other-file &&
  74        test_tick &&
  75        git commit -m other-file &&
  76        git stash apply &&
  77        test 3 = $(cat file) &&
  78        test 1 = $(git show :file) &&
  79        test 1 = $(git show HEAD:file)
  80'
  81
  82test_expect_success 'apply stashed changes (including index)' '
  83        git reset --hard HEAD^ &&
  84        echo 6 > other-file &&
  85        git add other-file &&
  86        test_tick &&
  87        git commit -m other-file &&
  88        git stash apply --index &&
  89        test 3 = $(cat file) &&
  90        test 2 = $(git show :file) &&
  91        test 1 = $(git show HEAD:file)
  92'
  93
  94test_expect_success 'unstashing in a subdirectory' '
  95        git reset --hard HEAD &&
  96        mkdir subdir &&
  97        (
  98                cd subdir &&
  99                git stash apply
 100        )
 101'
 102
 103test_expect_success 'stash drop complains of extra options' '
 104        test_must_fail git stash drop --foo
 105'
 106
 107test_expect_success 'drop top stash' '
 108        git reset --hard &&
 109        git stash list > stashlist1 &&
 110        echo 7 > file &&
 111        git stash &&
 112        git stash drop &&
 113        git stash list > stashlist2 &&
 114        test_cmp stashlist1 stashlist2 &&
 115        git stash apply &&
 116        test 3 = $(cat file) &&
 117        test 1 = $(git show :file) &&
 118        test 1 = $(git show HEAD:file)
 119'
 120
 121test_expect_success 'drop middle stash' '
 122        git reset --hard &&
 123        echo 8 > file &&
 124        git stash &&
 125        echo 9 > file &&
 126        git stash &&
 127        git stash drop stash@{1} &&
 128        test 2 = $(git stash list | wc -l) &&
 129        git stash apply &&
 130        test 9 = $(cat file) &&
 131        test 1 = $(git show :file) &&
 132        test 1 = $(git show HEAD:file) &&
 133        git reset --hard &&
 134        git stash drop &&
 135        git stash apply &&
 136        test 3 = $(cat file) &&
 137        test 1 = $(git show :file) &&
 138        test 1 = $(git show HEAD:file)
 139'
 140
 141test_expect_success 'stash pop' '
 142        git reset --hard &&
 143        git stash pop &&
 144        test 3 = $(cat file) &&
 145        test 1 = $(git show :file) &&
 146        test 1 = $(git show HEAD:file) &&
 147        test 0 = $(git stash list | wc -l)
 148'
 149
 150cat > expect << EOF
 151diff --git a/file2 b/file2
 152new file mode 100644
 153index 0000000..1fe912c
 154--- /dev/null
 155+++ b/file2
 156@@ -0,0 +1 @@
 157+bar2
 158EOF
 159
 160cat > expect1 << EOF
 161diff --git a/file b/file
 162index 257cc56..5716ca5 100644
 163--- a/file
 164+++ b/file
 165@@ -1 +1 @@
 166-foo
 167+bar
 168EOF
 169
 170cat > expect2 << EOF
 171diff --git a/file b/file
 172index 7601807..5716ca5 100644
 173--- a/file
 174+++ b/file
 175@@ -1 +1 @@
 176-baz
 177+bar
 178diff --git a/file2 b/file2
 179new file mode 100644
 180index 0000000..1fe912c
 181--- /dev/null
 182+++ b/file2
 183@@ -0,0 +1 @@
 184+bar2
 185EOF
 186
 187test_expect_success 'stash branch' '
 188        echo foo > file &&
 189        git commit file -m first &&
 190        echo bar > file &&
 191        echo bar2 > file2 &&
 192        git add file2 &&
 193        git stash &&
 194        echo baz > file &&
 195        git commit file -m second &&
 196        git stash branch stashbranch &&
 197        test refs/heads/stashbranch = $(git symbolic-ref HEAD) &&
 198        test $(git rev-parse HEAD) = $(git rev-parse master^) &&
 199        git diff --cached > output &&
 200        test_cmp output expect &&
 201        git diff > output &&
 202        test_cmp output expect1 &&
 203        git add file &&
 204        git commit -m alternate\ second &&
 205        git diff master..stashbranch > output &&
 206        test_cmp output expect2 &&
 207        test 0 = $(git stash list | wc -l)
 208'
 209
 210test_expect_success 'apply -q is quiet' '
 211        echo foo > file &&
 212        git stash &&
 213        git stash apply -q > output.out 2>&1 &&
 214        test_must_be_empty output.out
 215'
 216
 217test_expect_success 'save -q is quiet' '
 218        git stash save --quiet > output.out 2>&1 &&
 219        test_must_be_empty output.out
 220'
 221
 222test_expect_success 'pop -q is quiet' '
 223        git stash pop -q > output.out 2>&1 &&
 224        test_must_be_empty output.out
 225'
 226
 227test_expect_success 'pop -q --index works and is quiet' '
 228        echo foo > file &&
 229        git add file &&
 230        git stash save --quiet &&
 231        git stash pop -q --index > output.out 2>&1 &&
 232        test foo = "$(git show :file)" &&
 233        test_must_be_empty output.out
 234'
 235
 236test_expect_success 'drop -q is quiet' '
 237        git stash &&
 238        git stash drop -q > output.out 2>&1 &&
 239        test_must_be_empty output.out
 240'
 241
 242test_expect_success 'stash -k' '
 243        echo bar3 > file &&
 244        echo bar4 > file2 &&
 245        git add file2 &&
 246        git stash -k &&
 247        test bar,bar4 = $(cat file),$(cat file2)
 248'
 249
 250test_expect_success 'stash --no-keep-index' '
 251        echo bar33 > file &&
 252        echo bar44 > file2 &&
 253        git add file2 &&
 254        git stash --no-keep-index &&
 255        test bar,bar2 = $(cat file),$(cat file2)
 256'
 257
 258test_expect_success 'stash --invalid-option' '
 259        echo bar5 > file &&
 260        echo bar6 > file2 &&
 261        git add file2 &&
 262        test_must_fail git stash --invalid-option &&
 263        test_must_fail git stash save --invalid-option &&
 264        test bar5,bar6 = $(cat file),$(cat file2) &&
 265        git stash -- -message-starting-with-dash &&
 266        test bar,bar2 = $(cat file),$(cat file2)
 267'
 268
 269test_expect_success 'stash an added file' '
 270        git reset --hard &&
 271        echo new >file3 &&
 272        git add file3 &&
 273        git stash save "added file" &&
 274        ! test -r file3 &&
 275        git stash apply &&
 276        test new = "$(cat file3)"
 277'
 278
 279test_expect_success 'stash rm then recreate' '
 280        git reset --hard &&
 281        git rm file &&
 282        echo bar7 >file &&
 283        git stash save "rm then recreate" &&
 284        test bar = "$(cat file)" &&
 285        git stash apply &&
 286        test bar7 = "$(cat file)"
 287'
 288
 289test_expect_success 'stash rm and ignore' '
 290        git reset --hard &&
 291        git rm file &&
 292        echo file >.gitignore &&
 293        git stash save "rm and ignore" &&
 294        test bar = "$(cat file)" &&
 295        test file = "$(cat .gitignore)" &&
 296        git stash apply &&
 297        ! test -r file &&
 298        test file = "$(cat .gitignore)"
 299'
 300
 301test_expect_success 'stash rm and ignore (stage .gitignore)' '
 302        git reset --hard &&
 303        git rm file &&
 304        echo file >.gitignore &&
 305        git add .gitignore &&
 306        git stash save "rm and ignore (stage .gitignore)" &&
 307        test bar = "$(cat file)" &&
 308        ! test -r .gitignore &&
 309        git stash apply &&
 310        ! test -r file &&
 311        test file = "$(cat .gitignore)"
 312'
 313
 314test_expect_success SYMLINKS 'stash file to symlink' '
 315        git reset --hard &&
 316        rm file &&
 317        ln -s file2 file &&
 318        git stash save "file to symlink" &&
 319        test -f file &&
 320        test bar = "$(cat file)" &&
 321        git stash apply &&
 322        case "$(ls -l file)" in *" file -> file2") :;; *) false;; esac
 323'
 324
 325test_expect_success SYMLINKS 'stash file to symlink (stage rm)' '
 326        git reset --hard &&
 327        git rm file &&
 328        ln -s file2 file &&
 329        git stash save "file to symlink (stage rm)" &&
 330        test -f file &&
 331        test bar = "$(cat file)" &&
 332        git stash apply &&
 333        case "$(ls -l file)" in *" file -> file2") :;; *) false;; esac
 334'
 335
 336test_expect_success SYMLINKS 'stash file to symlink (full stage)' '
 337        git reset --hard &&
 338        rm file &&
 339        ln -s file2 file &&
 340        git add file &&
 341        git stash save "file to symlink (full stage)" &&
 342        test -f file &&
 343        test bar = "$(cat file)" &&
 344        git stash apply &&
 345        case "$(ls -l file)" in *" file -> file2") :;; *) false;; esac
 346'
 347
 348# This test creates a commit with a symlink used for the following tests
 349
 350test_expect_success 'stash symlink to file' '
 351        git reset --hard &&
 352        test_ln_s_add file filelink &&
 353        git commit -m "Add symlink" &&
 354        rm filelink &&
 355        cp file filelink &&
 356        git stash save "symlink to file"
 357'
 358
 359test_expect_success SYMLINKS 'this must have re-created the symlink' '
 360        test -h filelink &&
 361        case "$(ls -l filelink)" in *" filelink -> file") :;; *) false;; esac
 362'
 363
 364test_expect_success 'unstash must re-create the file' '
 365        git stash apply &&
 366        ! test -h filelink &&
 367        test bar = "$(cat file)"
 368'
 369
 370test_expect_success 'stash symlink to file (stage rm)' '
 371        git reset --hard &&
 372        git rm filelink &&
 373        cp file filelink &&
 374        git stash save "symlink to file (stage rm)"
 375'
 376
 377test_expect_success SYMLINKS 'this must have re-created the symlink' '
 378        test -h filelink &&
 379        case "$(ls -l filelink)" in *" filelink -> file") :;; *) false;; esac
 380'
 381
 382test_expect_success 'unstash must re-create the file' '
 383        git stash apply &&
 384        ! test -h filelink &&
 385        test bar = "$(cat file)"
 386'
 387
 388test_expect_success 'stash symlink to file (full stage)' '
 389        git reset --hard &&
 390        rm filelink &&
 391        cp file filelink &&
 392        git add filelink &&
 393        git stash save "symlink to file (full stage)"
 394'
 395
 396test_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
 401test_expect_success 'unstash must re-create the file' '
 402        git stash apply &&
 403        ! test -h filelink &&
 404        test bar = "$(cat file)"
 405'
 406
 407test_expect_failure 'stash directory to file' '
 408        git reset --hard &&
 409        mkdir dir &&
 410        echo foo >dir/file &&
 411        git add dir/file &&
 412        git commit -m "Add file in dir" &&
 413        rm -fr dir &&
 414        echo bar >dir &&
 415        git stash save "directory to file" &&
 416        test -d dir &&
 417        test foo = "$(cat dir/file)" &&
 418        test_must_fail git stash apply &&
 419        test bar = "$(cat dir)" &&
 420        git reset --soft HEAD^
 421'
 422
 423test_expect_failure 'stash file to directory' '
 424        git reset --hard &&
 425        rm file &&
 426        mkdir file &&
 427        echo foo >file/file &&
 428        git stash save "file to directory" &&
 429        test -f file &&
 430        test bar = "$(cat file)" &&
 431        git stash apply &&
 432        test -f file/file &&
 433        test foo = "$(cat file/file)"
 434'
 435
 436test_expect_success 'stash branch - no stashes on stack, stash-like argument' '
 437        git stash clear &&
 438        test_when_finished "git reset --hard HEAD" &&
 439        git reset --hard &&
 440        echo foo >> file &&
 441        STASH_ID=$(git stash create) &&
 442        git reset --hard &&
 443        git stash branch stash-branch ${STASH_ID} &&
 444        test_when_finished "git reset --hard HEAD && git checkout master && git branch -D stash-branch" &&
 445        test $(git ls-files --modified | wc -l) -eq 1
 446'
 447
 448test_expect_success 'stash branch - stashes on stack, stash-like argument' '
 449        git stash clear &&
 450        test_when_finished "git reset --hard HEAD" &&
 451        git reset --hard &&
 452        echo foo >> file &&
 453        git stash &&
 454        test_when_finished "git stash drop" &&
 455        echo bar >> file &&
 456        STASH_ID=$(git stash create) &&
 457        git reset --hard &&
 458        git stash branch stash-branch ${STASH_ID} &&
 459        test_when_finished "git reset --hard HEAD && git checkout master && git branch -D stash-branch" &&
 460        test $(git ls-files --modified | wc -l) -eq 1
 461'
 462
 463test_expect_success 'stash show format defaults to --stat' '
 464        git stash clear &&
 465        test_when_finished "git reset --hard HEAD" &&
 466        git reset --hard &&
 467        echo foo >> file &&
 468        git stash &&
 469        test_when_finished "git stash drop" &&
 470        echo bar >> file &&
 471        STASH_ID=$(git stash create) &&
 472        git reset --hard &&
 473        cat >expected <<-EOF &&
 474         file | 1 +
 475         1 file changed, 1 insertion(+)
 476        EOF
 477        git stash show ${STASH_ID} >actual &&
 478        test_i18ncmp expected actual
 479'
 480
 481test_expect_success 'stash show - stashes on stack, stash-like argument' '
 482        git stash clear &&
 483        test_when_finished "git reset --hard HEAD" &&
 484        git reset --hard &&
 485        echo foo >> file &&
 486        git stash &&
 487        test_when_finished "git stash drop" &&
 488        echo bar >> file &&
 489        STASH_ID=$(git stash create) &&
 490        git reset --hard &&
 491        echo "1 0       file" >expected &&
 492        git stash show --numstat ${STASH_ID} >actual &&
 493        test_cmp expected actual
 494'
 495
 496test_expect_success 'stash show -p - stashes on stack, stash-like argument' '
 497        git stash clear &&
 498        test_when_finished "git reset --hard HEAD" &&
 499        git reset --hard &&
 500        echo foo >> file &&
 501        git stash &&
 502        test_when_finished "git stash drop" &&
 503        echo bar >> file &&
 504        STASH_ID=$(git stash create) &&
 505        git reset --hard &&
 506        cat >expected <<-EOF &&
 507        diff --git a/file b/file
 508        index 7601807..935fbd3 100644
 509        --- a/file
 510        +++ b/file
 511        @@ -1 +1,2 @@
 512         baz
 513        +bar
 514        EOF
 515        git stash show -p ${STASH_ID} >actual &&
 516        test_cmp expected actual
 517'
 518
 519test_expect_success 'stash show - no stashes on stack, stash-like argument' '
 520        git stash clear &&
 521        test_when_finished "git reset --hard HEAD" &&
 522        git reset --hard &&
 523        echo foo >> file &&
 524        STASH_ID=$(git stash create) &&
 525        git reset --hard &&
 526        echo "1 0       file" >expected &&
 527        git stash show --numstat ${STASH_ID} >actual &&
 528        test_cmp expected actual
 529'
 530
 531test_expect_success 'stash show -p - no 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        STASH_ID=$(git stash create) &&
 537        git reset --hard &&
 538        cat >expected <<-EOF &&
 539        diff --git a/file b/file
 540        index 7601807..71b52c4 100644
 541        --- a/file
 542        +++ b/file
 543        @@ -1 +1,2 @@
 544         baz
 545        +foo
 546        EOF
 547        git stash show -p ${STASH_ID} >actual &&
 548        test_cmp expected actual
 549'
 550
 551test_expect_success 'stash drop - fail early if specified stash is not a stash reference' '
 552        git stash clear &&
 553        test_when_finished "git reset --hard HEAD && git stash clear" &&
 554        git reset --hard &&
 555        echo foo > file &&
 556        git stash &&
 557        echo bar > file &&
 558        git stash &&
 559        test_must_fail git stash drop $(git rev-parse stash@{0}) &&
 560        git stash pop &&
 561        test bar = "$(cat file)" &&
 562        git reset --hard HEAD
 563'
 564
 565test_expect_success 'stash pop - fail early if specified stash is not a stash reference' '
 566        git stash clear &&
 567        test_when_finished "git reset --hard HEAD && git stash clear" &&
 568        git reset --hard &&
 569        echo foo > file &&
 570        git stash &&
 571        echo bar > file &&
 572        git stash &&
 573        test_must_fail git stash pop $(git rev-parse stash@{0}) &&
 574        git stash pop &&
 575        test bar = "$(cat file)" &&
 576        git reset --hard HEAD
 577'
 578
 579test_expect_success 'ref with non-existent reflog' '
 580        git stash clear &&
 581        echo bar5 > file &&
 582        echo bar6 > file2 &&
 583        git add file2 &&
 584        git stash &&
 585        test_must_fail git rev-parse --quiet --verify does-not-exist &&
 586        test_must_fail git stash drop does-not-exist &&
 587        test_must_fail git stash drop does-not-exist@{0} &&
 588        test_must_fail git stash pop does-not-exist &&
 589        test_must_fail git stash pop does-not-exist@{0} &&
 590        test_must_fail git stash apply does-not-exist &&
 591        test_must_fail git stash apply does-not-exist@{0} &&
 592        test_must_fail git stash show does-not-exist &&
 593        test_must_fail git stash show does-not-exist@{0} &&
 594        test_must_fail git stash branch tmp does-not-exist &&
 595        test_must_fail git stash branch tmp does-not-exist@{0} &&
 596        git stash drop
 597'
 598
 599test_expect_success 'invalid ref of the form stash@{n}, n >= N' '
 600        git stash clear &&
 601        test_must_fail git stash drop stash@{0} &&
 602        echo bar5 > file &&
 603        echo bar6 > file2 &&
 604        git add file2 &&
 605        git stash &&
 606        test_must_fail git stash drop stash@{1} &&
 607        test_must_fail git stash pop stash@{1} &&
 608        test_must_fail git stash apply stash@{1} &&
 609        test_must_fail git stash show stash@{1} &&
 610        test_must_fail git stash branch tmp stash@{1} &&
 611        git stash drop
 612'
 613
 614test_expect_success 'stash branch should not drop the stash if the branch exists' '
 615        git stash clear &&
 616        echo foo >file &&
 617        git add file &&
 618        git commit -m initial &&
 619        echo bar >file &&
 620        git stash &&
 621        test_must_fail git stash branch master stash@{0} &&
 622        git rev-parse stash@{0} --
 623'
 624
 625test_expect_success 'stash apply shows status same as git status (relative to current directory)' '
 626        git stash clear &&
 627        echo 1 >subdir/subfile1 &&
 628        echo 2 >subdir/subfile2 &&
 629        git add subdir/subfile1 &&
 630        git commit -m subdir &&
 631        (
 632                cd subdir &&
 633                echo x >subfile1 &&
 634                echo x >../file &&
 635                git status >../expect &&
 636                git stash &&
 637                sane_unset GIT_MERGE_VERBOSITY &&
 638                git stash apply
 639        ) |
 640        sed -e 1,2d >actual && # drop "Saved..." and "HEAD is now..."
 641        test_i18ncmp expect actual
 642'
 643
 644cat > expect << EOF
 645diff --git a/HEAD b/HEAD
 646new file mode 100644
 647index 0000000..fe0cbee
 648--- /dev/null
 649+++ b/HEAD
 650@@ -0,0 +1 @@
 651+file-not-a-ref
 652EOF
 653
 654test_expect_success 'stash where working directory contains "HEAD" file' '
 655        git stash clear &&
 656        git reset --hard &&
 657        echo file-not-a-ref > HEAD &&
 658        git add HEAD &&
 659        test_tick &&
 660        git stash &&
 661        git diff-files --quiet &&
 662        git diff-index --cached --quiet HEAD &&
 663        test "$(git rev-parse stash^)" = "$(git rev-parse HEAD)" &&
 664        git diff stash^..stash > output &&
 665        test_cmp output expect
 666'
 667
 668test_expect_success 'store called with invalid commit' '
 669        test_must_fail git stash store foo
 670'
 671
 672test_expect_success 'store updates stash ref and reflog' '
 673        git stash clear &&
 674        git reset --hard &&
 675        echo quux >bazzy &&
 676        git add bazzy &&
 677        STASH_ID=$(git stash create) &&
 678        git reset --hard &&
 679        ! grep quux bazzy &&
 680        git stash store -m quuxery $STASH_ID &&
 681        test $(cat .git/refs/stash) = $STASH_ID &&
 682        grep $STASH_ID .git/logs/refs/stash &&
 683        git stash pop &&
 684        grep quux bazzy
 685'
 686
 687test_expect_success 'handle stash specification with spaces' '
 688        git stash clear &&
 689        echo pig >file &&
 690        git stash &&
 691        stamp=$(git log -g --format="%cd" -1 refs/stash) &&
 692        test_tick &&
 693        echo cow >file &&
 694        git stash &&
 695        git stash apply "stash@{$stamp}" &&
 696        grep pig file
 697'
 698
 699test_expect_success 'setup stash with index and worktree changes' '
 700        git stash clear &&
 701        git reset --hard &&
 702        echo index >file &&
 703        git add file &&
 704        echo working >file &&
 705        git stash
 706'
 707
 708test_expect_success 'stash list implies --first-parent -m' '
 709        cat >expect <<-EOF &&
 710        stash@{0}
 711
 712        diff --git a/file b/file
 713        index 257cc56..d26b33d 100644
 714        --- a/file
 715        +++ b/file
 716        @@ -1 +1 @@
 717        -foo
 718        +working
 719        EOF
 720        git stash list --format=%gd -p >actual &&
 721        test_cmp expect actual
 722'
 723
 724test_expect_success 'stash list --cc shows combined diff' '
 725        cat >expect <<-\EOF &&
 726        stash@{0}
 727
 728        diff --cc file
 729        index 257cc56,9015a7a..d26b33d
 730        --- a/file
 731        +++ b/file
 732        @@@ -1,1 -1,1 +1,1 @@@
 733        - foo
 734         -index
 735        ++working
 736        EOF
 737        git stash list --format=%gd -p --cc >actual &&
 738        test_cmp expect actual
 739'
 740
 741test_done