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