0b52a3497eefb29a71748d99d4cc2c6e59477291
   1#!/bin/sh
   2
   3test_description='pulling into void'
   4
   5. ./test-lib.sh
   6
   7modify () {
   8        sed -e "$1" <"$2" >"$2.x" &&
   9        mv "$2.x" "$2"
  10}
  11
  12test_pull_autostash () {
  13        git reset --hard before-rebase &&
  14        echo dirty >new_file &&
  15        git add new_file &&
  16        git pull "$@" . copy &&
  17        test_cmp_rev HEAD^ copy &&
  18        test "$(cat new_file)" = dirty &&
  19        test "$(cat file)" = "modified again"
  20}
  21
  22test_expect_success setup '
  23        echo file >file &&
  24        git add file &&
  25        git commit -a -m original
  26'
  27
  28test_expect_success 'pulling into void' '
  29        git init cloned &&
  30        (
  31                cd cloned &&
  32                git pull ..
  33        ) &&
  34        test -f file &&
  35        test -f cloned/file &&
  36        test_cmp file cloned/file
  37'
  38
  39test_expect_success 'pulling into void using master:master' '
  40        git init cloned-uho &&
  41        (
  42                cd cloned-uho &&
  43                git pull .. master:master
  44        ) &&
  45        test -f file &&
  46        test -f cloned-uho/file &&
  47        test_cmp file cloned-uho/file
  48'
  49
  50test_expect_success 'pulling into void does not overwrite untracked files' '
  51        git init cloned-untracked &&
  52        (
  53                cd cloned-untracked &&
  54                echo untracked >file &&
  55                test_must_fail git pull .. master &&
  56                echo untracked >expect &&
  57                test_cmp expect file
  58        )
  59'
  60
  61test_expect_success 'pulling into void does not overwrite staged files' '
  62        git init cloned-staged-colliding &&
  63        (
  64                cd cloned-staged-colliding &&
  65                echo "alternate content" >file &&
  66                git add file &&
  67                test_must_fail git pull .. master &&
  68                echo "alternate content" >expect &&
  69                test_cmp expect file &&
  70                git cat-file blob :file >file.index &&
  71                test_cmp expect file.index
  72        )
  73'
  74
  75test_expect_success 'pulling into void does not remove new staged files' '
  76        git init cloned-staged-new &&
  77        (
  78                cd cloned-staged-new &&
  79                echo "new tracked file" >newfile &&
  80                git add newfile &&
  81                git pull .. master &&
  82                echo "new tracked file" >expect &&
  83                test_cmp expect newfile &&
  84                git cat-file blob :newfile >newfile.index &&
  85                test_cmp expect newfile.index
  86        )
  87'
  88
  89test_expect_success 'pulling into void must not create an octopus' '
  90        git init cloned-octopus &&
  91        (
  92                cd cloned-octopus &&
  93                test_must_fail git pull .. master master &&
  94                ! test -f file
  95        )
  96'
  97
  98test_expect_success 'test . as a remote' '
  99        git branch copy master &&
 100        git config branch.copy.remote . &&
 101        git config branch.copy.merge refs/heads/master &&
 102        echo updated >file &&
 103        git commit -a -m updated &&
 104        git checkout copy &&
 105        test "$(cat file)" = file &&
 106        git pull &&
 107        test "$(cat file)" = updated &&
 108        git reflog -1 >reflog.actual &&
 109        sed "s/^[0-9a-f][0-9a-f]*/OBJID/" reflog.actual >reflog.fuzzy &&
 110        echo "OBJID HEAD@{0}: pull: Fast-forward" >reflog.expected &&
 111        test_cmp reflog.expected reflog.fuzzy
 112'
 113
 114test_expect_success 'the default remote . should not break explicit pull' '
 115        git checkout -b second master^ &&
 116        echo modified >file &&
 117        git commit -a -m modified &&
 118        git checkout copy &&
 119        git reset --hard HEAD^ &&
 120        test "$(cat file)" = file &&
 121        git pull . second &&
 122        test "$(cat file)" = modified &&
 123        git reflog -1 >reflog.actual &&
 124        sed "s/^[0-9a-f][0-9a-f]*/OBJID/" reflog.actual >reflog.fuzzy &&
 125        echo "OBJID HEAD@{0}: pull . second: Fast-forward" >reflog.expected &&
 126        test_cmp reflog.expected reflog.fuzzy
 127'
 128
 129test_expect_success 'fail if wildcard spec does not match any refs' '
 130        git checkout -b test copy^ &&
 131        test_when_finished "git checkout -f copy && git branch -D test" &&
 132        test "$(cat file)" = file &&
 133        test_must_fail git pull . "refs/nonexisting1/*:refs/nonexisting2/*" 2>err &&
 134        test_i18ngrep "no candidates for merging" err &&
 135        test "$(cat file)" = file
 136'
 137
 138test_expect_success 'fail if no branches specified with non-default remote' '
 139        git remote add test_remote . &&
 140        test_when_finished "git remote remove test_remote" &&
 141        git checkout -b test copy^ &&
 142        test_when_finished "git checkout -f copy && git branch -D test" &&
 143        test "$(cat file)" = file &&
 144        test_config branch.test.remote origin &&
 145        test_must_fail git pull test_remote 2>err &&
 146        test_i18ngrep "specify a branch on the command line" err &&
 147        test "$(cat file)" = file
 148'
 149
 150test_expect_success 'fail if not on a branch' '
 151        git remote add origin . &&
 152        test_when_finished "git remote remove origin" &&
 153        git checkout HEAD^ &&
 154        test_when_finished "git checkout -f copy" &&
 155        test "$(cat file)" = file &&
 156        test_must_fail git pull 2>err &&
 157        test_i18ngrep "not currently on a branch" err &&
 158        test "$(cat file)" = file
 159'
 160
 161test_expect_success 'fail if no configuration for current branch' '
 162        git remote add test_remote . &&
 163        test_when_finished "git remote remove test_remote" &&
 164        git checkout -b test copy^ &&
 165        test_when_finished "git checkout -f copy && git branch -D test" &&
 166        test_config branch.test.remote test_remote &&
 167        test "$(cat file)" = file &&
 168        test_must_fail git pull 2>err &&
 169        test_i18ngrep "no tracking information" err &&
 170        test "$(cat file)" = file
 171'
 172
 173test_expect_success 'pull --all: fail if no configuration for current branch' '
 174        git remote add test_remote . &&
 175        test_when_finished "git remote remove test_remote" &&
 176        git checkout -b test copy^ &&
 177        test_when_finished "git checkout -f copy && git branch -D test" &&
 178        test_config branch.test.remote test_remote &&
 179        test "$(cat file)" = file &&
 180        test_must_fail git pull --all 2>err &&
 181        test_i18ngrep "There is no tracking information" err &&
 182        test "$(cat file)" = file
 183'
 184
 185test_expect_success 'fail if upstream branch does not exist' '
 186        git checkout -b test copy^ &&
 187        test_when_finished "git checkout -f copy && git branch -D test" &&
 188        test_config branch.test.remote . &&
 189        test_config branch.test.merge refs/heads/nonexisting &&
 190        test "$(cat file)" = file &&
 191        test_must_fail git pull 2>err &&
 192        test_i18ngrep "no such ref was fetched" err &&
 193        test "$(cat file)" = file
 194'
 195
 196test_expect_success 'fail if the index has unresolved entries' '
 197        git checkout -b third second^ &&
 198        test_when_finished "git checkout -f copy && git branch -D third" &&
 199        test "$(cat file)" = file &&
 200        test_commit modified2 file &&
 201        test -z "$(git ls-files -u)" &&
 202        test_must_fail git pull . second &&
 203        test -n "$(git ls-files -u)" &&
 204        cp file expected &&
 205        test_must_fail git pull . second 2>err &&
 206        test_i18ngrep "Pull is not possible because you have unmerged files" err &&
 207        test_cmp expected file &&
 208        git add file &&
 209        test -z "$(git ls-files -u)" &&
 210        test_must_fail git pull . second 2>err &&
 211        test_i18ngrep "You have not concluded your merge" err &&
 212        test_cmp expected file
 213'
 214
 215test_expect_success 'fast-forwards working tree if branch head is updated' '
 216        git checkout -b third second^ &&
 217        test_when_finished "git checkout -f copy && git branch -D third" &&
 218        test "$(cat file)" = file &&
 219        git pull . second:third 2>err &&
 220        test_i18ngrep "fetch updated the current branch head" err &&
 221        test "$(cat file)" = modified &&
 222        test "$(git rev-parse third)" = "$(git rev-parse second)"
 223'
 224
 225test_expect_success 'fast-forward fails with conflicting work tree' '
 226        git checkout -b third second^ &&
 227        test_when_finished "git checkout -f copy && git branch -D third" &&
 228        test "$(cat file)" = file &&
 229        echo conflict >file &&
 230        test_must_fail git pull . second:third 2>err &&
 231        test_i18ngrep "Cannot fast-forward your working tree" err &&
 232        test "$(cat file)" = conflict &&
 233        test "$(git rev-parse third)" = "$(git rev-parse second)"
 234'
 235
 236test_expect_success '--rebase' '
 237        git branch to-rebase &&
 238        echo modified again > file &&
 239        git commit -m file file &&
 240        git checkout to-rebase &&
 241        echo new > file2 &&
 242        git add file2 &&
 243        git commit -m "new file" &&
 244        git tag before-rebase &&
 245        git pull --rebase . copy &&
 246        test "$(git rev-parse HEAD^)" = "$(git rev-parse copy)" &&
 247        test new = "$(git show HEAD:file2)"
 248'
 249
 250test_expect_success '--rebase fails with multiple branches' '
 251        git reset --hard before-rebase &&
 252        test_must_fail git pull --rebase . copy master 2>err &&
 253        test "$(git rev-parse HEAD)" = "$(git rev-parse before-rebase)" &&
 254        test_i18ngrep "Cannot rebase onto multiple branches" err &&
 255        test modified = "$(git show HEAD:file)"
 256'
 257
 258test_expect_success 'pull --rebase succeeds with dirty working directory and rebase.autostash set' '
 259        test_config rebase.autostash true &&
 260        test_pull_autostash --rebase
 261'
 262
 263test_expect_success 'pull --rebase --autostash & rebase.autostash=true' '
 264        test_config rebase.autostash true &&
 265        test_pull_autostash --rebase --autostash
 266'
 267
 268test_expect_success 'pull --rebase --autostash & rebase.autostash=false' '
 269        test_config rebase.autostash false &&
 270        test_pull_autostash --rebase --autostash
 271'
 272
 273test_expect_success 'pull --rebase --autostash & rebase.autostash unset' '
 274        test_unconfig rebase.autostash &&
 275        test_pull_autostash --rebase --autostash
 276'
 277
 278test_expect_success 'pull --rebase --no-autostash & rebase.autostash=true' '
 279        test_config rebase.autostash true &&
 280        git reset --hard before-rebase &&
 281        echo dirty >new_file &&
 282        git add new_file &&
 283        test_must_fail git pull --rebase --no-autostash . copy 2>err &&
 284        test_i18ngrep "Cannot pull with rebase: Your index contains uncommitted changes." err
 285'
 286
 287test_expect_success 'pull --rebase --no-autostash & rebase.autostash=false' '
 288        test_config rebase.autostash false &&
 289        git reset --hard before-rebase &&
 290        echo dirty >new_file &&
 291        git add new_file &&
 292        test_must_fail git pull --rebase --no-autostash . copy 2>err &&
 293        test_i18ngrep "Cannot pull with rebase: Your index contains uncommitted changes." err
 294'
 295
 296test_expect_success 'pull --rebase --no-autostash & rebase.autostash unset' '
 297        test_unconfig rebase.autostash &&
 298        git reset --hard before-rebase &&
 299        echo dirty >new_file &&
 300        git add new_file &&
 301        test_must_fail git pull --rebase --no-autostash . copy 2>err &&
 302        test_i18ngrep "Cannot pull with rebase: Your index contains uncommitted changes." err
 303'
 304
 305test_expect_success 'pull --autostash (without --rebase) should error out' '
 306        test_must_fail git pull --autostash . copy 2>err &&
 307        test_i18ngrep "only valid with --rebase" err
 308'
 309
 310test_expect_success 'pull --no-autostash (without --rebase) should error out' '
 311        test_must_fail git pull --no-autostash . copy 2>err &&
 312        test_i18ngrep "only valid with --rebase" err
 313'
 314
 315test_expect_success 'pull.rebase' '
 316        git reset --hard before-rebase &&
 317        test_config pull.rebase true &&
 318        git pull . copy &&
 319        test "$(git rev-parse HEAD^)" = "$(git rev-parse copy)" &&
 320        test new = "$(git show HEAD:file2)"
 321'
 322
 323test_expect_success 'branch.to-rebase.rebase' '
 324        git reset --hard before-rebase &&
 325        test_config branch.to-rebase.rebase true &&
 326        git pull . copy &&
 327        test "$(git rev-parse HEAD^)" = "$(git rev-parse copy)" &&
 328        test new = "$(git show HEAD:file2)"
 329'
 330
 331test_expect_success 'branch.to-rebase.rebase should override pull.rebase' '
 332        git reset --hard before-rebase &&
 333        test_config pull.rebase true &&
 334        test_config branch.to-rebase.rebase false &&
 335        git pull . copy &&
 336        test "$(git rev-parse HEAD^)" != "$(git rev-parse copy)" &&
 337        test new = "$(git show HEAD:file2)"
 338'
 339
 340# add a feature branch, keep-merge, that is merged into master, so the
 341# test can try preserving the merge commit (or not) with various
 342# --rebase flags/pull.rebase settings.
 343test_expect_success 'preserve merge setup' '
 344        git reset --hard before-rebase &&
 345        git checkout -b keep-merge second^ &&
 346        test_commit file3 &&
 347        git checkout to-rebase &&
 348        git merge keep-merge &&
 349        git tag before-preserve-rebase
 350'
 351
 352test_expect_success 'pull.rebase=false create a new merge commit' '
 353        git reset --hard before-preserve-rebase &&
 354        test_config pull.rebase false &&
 355        git pull . copy &&
 356        test "$(git rev-parse HEAD^1)" = "$(git rev-parse before-preserve-rebase)" &&
 357        test "$(git rev-parse HEAD^2)" = "$(git rev-parse copy)" &&
 358        test file3 = "$(git show HEAD:file3.t)"
 359'
 360
 361test_expect_success 'pull.rebase=true flattens keep-merge' '
 362        git reset --hard before-preserve-rebase &&
 363        test_config pull.rebase true &&
 364        git pull . copy &&
 365        test "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" &&
 366        test file3 = "$(git show HEAD:file3.t)"
 367'
 368
 369test_expect_success 'pull.rebase=1 is treated as true and flattens keep-merge' '
 370        git reset --hard before-preserve-rebase &&
 371        test_config pull.rebase 1 &&
 372        git pull . copy &&
 373        test "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" &&
 374        test file3 = "$(git show HEAD:file3.t)"
 375'
 376
 377test_expect_success 'pull.rebase=preserve rebases and merges keep-merge' '
 378        git reset --hard before-preserve-rebase &&
 379        test_config pull.rebase preserve &&
 380        git pull . copy &&
 381        test "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" &&
 382        test "$(git rev-parse HEAD^2)" = "$(git rev-parse keep-merge)"
 383'
 384
 385test_expect_success 'pull.rebase=interactive' '
 386        write_script "$TRASH_DIRECTORY/fake-editor" <<-\EOF &&
 387        echo I was here >fake.out &&
 388        false
 389        EOF
 390        test_set_editor "$TRASH_DIRECTORY/fake-editor" &&
 391        test_must_fail git pull --rebase=interactive . copy &&
 392        test "I was here" = "$(cat fake.out)"
 393'
 394
 395test_expect_success 'pull.rebase=invalid fails' '
 396        git reset --hard before-preserve-rebase &&
 397        test_config pull.rebase invalid &&
 398        ! git pull . copy
 399'
 400
 401test_expect_success '--rebase=false create a new merge commit' '
 402        git reset --hard before-preserve-rebase &&
 403        test_config pull.rebase true &&
 404        git pull --rebase=false . copy &&
 405        test "$(git rev-parse HEAD^1)" = "$(git rev-parse before-preserve-rebase)" &&
 406        test "$(git rev-parse HEAD^2)" = "$(git rev-parse copy)" &&
 407        test file3 = "$(git show HEAD:file3.t)"
 408'
 409
 410test_expect_success '--rebase=true rebases and flattens keep-merge' '
 411        git reset --hard before-preserve-rebase &&
 412        test_config pull.rebase preserve &&
 413        git pull --rebase=true . copy &&
 414        test "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" &&
 415        test file3 = "$(git show HEAD:file3.t)"
 416'
 417
 418test_expect_success '--rebase=preserve rebases and merges keep-merge' '
 419        git reset --hard before-preserve-rebase &&
 420        test_config pull.rebase true &&
 421        git pull --rebase=preserve . copy &&
 422        test "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" &&
 423        test "$(git rev-parse HEAD^2)" = "$(git rev-parse keep-merge)"
 424'
 425
 426test_expect_success '--rebase=invalid fails' '
 427        git reset --hard before-preserve-rebase &&
 428        ! git pull --rebase=invalid . copy
 429'
 430
 431test_expect_success '--rebase overrides pull.rebase=preserve and flattens keep-merge' '
 432        git reset --hard before-preserve-rebase &&
 433        test_config pull.rebase preserve &&
 434        git pull --rebase . copy &&
 435        test "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" &&
 436        test file3 = "$(git show HEAD:file3.t)"
 437'
 438
 439test_expect_success '--rebase with rebased upstream' '
 440
 441        git remote add -f me . &&
 442        git checkout copy &&
 443        git tag copy-orig &&
 444        git reset --hard HEAD^ &&
 445        echo conflicting modification > file &&
 446        git commit -m conflict file &&
 447        git checkout to-rebase &&
 448        echo file > file2 &&
 449        git commit -m to-rebase file2 &&
 450        git tag to-rebase-orig &&
 451        git pull --rebase me copy &&
 452        test "conflicting modification" = "$(cat file)" &&
 453        test file = "$(cat file2)"
 454
 455'
 456
 457test_expect_success '--rebase -f with rebased upstream' '
 458        test_when_finished "test_might_fail git rebase --abort" &&
 459        git reset --hard to-rebase-orig &&
 460        git pull --rebase -f me copy &&
 461        test "conflicting modification" = "$(cat file)" &&
 462        test file = "$(cat file2)"
 463'
 464
 465test_expect_success '--rebase with rebased default upstream' '
 466
 467        git update-ref refs/remotes/me/copy copy-orig &&
 468        git checkout --track -b to-rebase2 me/copy &&
 469        git reset --hard to-rebase-orig &&
 470        git pull --rebase &&
 471        test "conflicting modification" = "$(cat file)" &&
 472        test file = "$(cat file2)"
 473
 474'
 475
 476test_expect_success 'rebased upstream + fetch + pull --rebase' '
 477
 478        git update-ref refs/remotes/me/copy copy-orig &&
 479        git reset --hard to-rebase-orig &&
 480        git checkout --track -b to-rebase3 me/copy &&
 481        git reset --hard to-rebase-orig &&
 482        git fetch &&
 483        git pull --rebase &&
 484        test "conflicting modification" = "$(cat file)" &&
 485        test file = "$(cat file2)"
 486
 487'
 488
 489test_expect_success 'pull --rebase dies early with dirty working directory' '
 490
 491        git checkout to-rebase &&
 492        git update-ref refs/remotes/me/copy copy^ &&
 493        COPY="$(git rev-parse --verify me/copy)" &&
 494        git rebase --onto $COPY copy &&
 495        test_config branch.to-rebase.remote me &&
 496        test_config branch.to-rebase.merge refs/heads/copy &&
 497        test_config branch.to-rebase.rebase true &&
 498        echo dirty >> file &&
 499        git add file &&
 500        test_must_fail git pull &&
 501        test "$COPY" = "$(git rev-parse --verify me/copy)" &&
 502        git checkout HEAD -- file &&
 503        git pull &&
 504        test "$COPY" != "$(git rev-parse --verify me/copy)"
 505
 506'
 507
 508test_expect_success 'pull --rebase works on branch yet to be born' '
 509        git rev-parse master >expect &&
 510        mkdir empty_repo &&
 511        (cd empty_repo &&
 512         git init &&
 513         git pull --rebase .. master &&
 514         git rev-parse HEAD >../actual
 515        ) &&
 516        test_cmp expect actual
 517'
 518
 519test_expect_success 'pull --rebase fails on unborn branch with staged changes' '
 520        test_when_finished "rm -rf empty_repo2" &&
 521        git init empty_repo2 &&
 522        (
 523                cd empty_repo2 &&
 524                echo staged-file >staged-file &&
 525                git add staged-file &&
 526                test "$(git ls-files)" = staged-file &&
 527                test_must_fail git pull --rebase .. master 2>err &&
 528                test "$(git ls-files)" = staged-file &&
 529                test "$(git show :staged-file)" = staged-file &&
 530                test_i18ngrep "unborn branch with changes added to the index" err
 531        )
 532'
 533
 534test_expect_success 'setup for detecting upstreamed changes' '
 535        mkdir src &&
 536        (cd src &&
 537         git init &&
 538         printf "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n" > stuff &&
 539         git add stuff &&
 540         git commit -m "Initial revision"
 541        ) &&
 542        git clone src dst &&
 543        (cd src &&
 544         modify s/5/43/ stuff &&
 545         git commit -a -m "5->43" &&
 546         modify s/6/42/ stuff &&
 547         git commit -a -m "Make it bigger"
 548        ) &&
 549        (cd dst &&
 550         modify s/5/43/ stuff &&
 551         git commit -a -m "Independent discovery of 5->43"
 552        )
 553'
 554
 555test_expect_success 'git pull --rebase detects upstreamed changes' '
 556        (cd dst &&
 557         git pull --rebase &&
 558         test -z "$(git ls-files -u)"
 559        )
 560'
 561
 562test_expect_success 'setup for avoiding reapplying old patches' '
 563        (cd dst &&
 564         test_might_fail git rebase --abort &&
 565         git reset --hard origin/master
 566        ) &&
 567        git clone --bare src src-replace.git &&
 568        rm -rf src &&
 569        mv src-replace.git src &&
 570        (cd dst &&
 571         modify s/2/22/ stuff &&
 572         git commit -a -m "Change 2" &&
 573         modify s/3/33/ stuff &&
 574         git commit -a -m "Change 3" &&
 575         modify s/4/44/ stuff &&
 576         git commit -a -m "Change 4" &&
 577         git push &&
 578
 579         modify s/44/55/ stuff &&
 580         git commit --amend -a -m "Modified Change 4"
 581        )
 582'
 583
 584test_expect_success 'git pull --rebase does not reapply old patches' '
 585        (cd dst &&
 586         test_must_fail git pull --rebase &&
 587         test 1 = $(find .git/rebase-apply -name "000*" | wc -l)
 588        )
 589'
 590
 591test_expect_success 'git pull --rebase against local branch' '
 592        git checkout -b copy2 to-rebase-orig &&
 593        git pull --rebase . to-rebase &&
 594        test "conflicting modification" = "$(cat file)" &&
 595        test file = "$(cat file2)"
 596'
 597
 598test_done