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