t / t5516-fetch-push.shon commit Refuse updating the current branch in a non-bare repository via push (acd2a45)
   1#!/bin/sh
   2
   3test_description='fetching and pushing, with or without wildcard'
   4
   5. ./test-lib.sh
   6
   7D=`pwd`
   8
   9mk_empty () {
  10        rm -fr testrepo &&
  11        mkdir testrepo &&
  12        (
  13                cd testrepo &&
  14                git init &&
  15                git config receive.denyCurrentBranch warn &&
  16                mv .git/hooks .git/hooks-disabled
  17        )
  18}
  19
  20mk_test () {
  21        mk_empty &&
  22        (
  23                for ref in "$@"
  24                do
  25                        git push testrepo $the_first_commit:refs/$ref || {
  26                                echo "Oops, push refs/$ref failure"
  27                                exit 1
  28                        }
  29                done &&
  30                cd testrepo &&
  31                for ref in "$@"
  32                do
  33                        r=$(git show-ref -s --verify refs/$ref) &&
  34                        test "z$r" = "z$the_first_commit" || {
  35                                echo "Oops, refs/$ref is wrong"
  36                                exit 1
  37                        }
  38                done &&
  39                git fsck --full
  40        )
  41}
  42
  43mk_child() {
  44        rm -rf "$1" &&
  45        git clone testrepo "$1"
  46}
  47
  48check_push_result () {
  49        (
  50                cd testrepo &&
  51                it="$1" &&
  52                shift
  53                for ref in "$@"
  54                do
  55                        r=$(git show-ref -s --verify refs/$ref) &&
  56                        test "z$r" = "z$it" || {
  57                                echo "Oops, refs/$ref is wrong"
  58                                exit 1
  59                        }
  60                done &&
  61                git fsck --full
  62        )
  63}
  64
  65test_expect_success setup '
  66
  67        : >path1 &&
  68        git add path1 &&
  69        test_tick &&
  70        git commit -a -m repo &&
  71        the_first_commit=$(git show-ref -s --verify refs/heads/master) &&
  72
  73        : >path2 &&
  74        git add path2 &&
  75        test_tick &&
  76        git commit -a -m second &&
  77        the_commit=$(git show-ref -s --verify refs/heads/master)
  78
  79'
  80
  81test_expect_success 'fetch without wildcard' '
  82        mk_empty &&
  83        (
  84                cd testrepo &&
  85                git fetch .. refs/heads/master:refs/remotes/origin/master &&
  86
  87                r=$(git show-ref -s --verify refs/remotes/origin/master) &&
  88                test "z$r" = "z$the_commit" &&
  89
  90                test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
  91        )
  92'
  93
  94test_expect_success 'fetch with wildcard' '
  95        mk_empty &&
  96        (
  97                cd testrepo &&
  98                git config remote.up.url .. &&
  99                git config remote.up.fetch "refs/heads/*:refs/remotes/origin/*" &&
 100                git fetch up &&
 101
 102                r=$(git show-ref -s --verify refs/remotes/origin/master) &&
 103                test "z$r" = "z$the_commit" &&
 104
 105                test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
 106        )
 107'
 108
 109test_expect_success 'fetch with insteadOf' '
 110        mk_empty &&
 111        (
 112                TRASH=$(pwd)/ &&
 113                cd testrepo &&
 114                git config "url.$TRASH.insteadOf" trash/ &&
 115                git config remote.up.url trash/. &&
 116                git config remote.up.fetch "refs/heads/*:refs/remotes/origin/*" &&
 117                git fetch up &&
 118
 119                r=$(git show-ref -s --verify refs/remotes/origin/master) &&
 120                test "z$r" = "z$the_commit" &&
 121
 122                test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
 123        )
 124'
 125
 126test_expect_success 'push without wildcard' '
 127        mk_empty &&
 128
 129        git push testrepo refs/heads/master:refs/remotes/origin/master &&
 130        (
 131                cd testrepo &&
 132                r=$(git show-ref -s --verify refs/remotes/origin/master) &&
 133                test "z$r" = "z$the_commit" &&
 134
 135                test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
 136        )
 137'
 138
 139test_expect_success 'push with wildcard' '
 140        mk_empty &&
 141
 142        git push testrepo "refs/heads/*:refs/remotes/origin/*" &&
 143        (
 144                cd testrepo &&
 145                r=$(git show-ref -s --verify refs/remotes/origin/master) &&
 146                test "z$r" = "z$the_commit" &&
 147
 148                test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
 149        )
 150'
 151
 152test_expect_success 'push with insteadOf' '
 153        mk_empty &&
 154        TRASH="$(pwd)/" &&
 155        git config "url.$TRASH.insteadOf" trash/ &&
 156        git push trash/testrepo refs/heads/master:refs/remotes/origin/master &&
 157        (
 158                cd testrepo &&
 159                r=$(git show-ref -s --verify refs/remotes/origin/master) &&
 160                test "z$r" = "z$the_commit" &&
 161
 162                test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
 163        )
 164'
 165
 166test_expect_success 'push with matching heads' '
 167
 168        mk_test heads/master &&
 169        git push testrepo &&
 170        check_push_result $the_commit heads/master
 171
 172'
 173
 174test_expect_success 'push with matching heads on the command line' '
 175
 176        mk_test heads/master &&
 177        git push testrepo : &&
 178        check_push_result $the_commit heads/master
 179
 180'
 181
 182test_expect_success 'failed (non-fast-forward) push with matching heads' '
 183
 184        mk_test heads/master &&
 185        git push testrepo : &&
 186        git commit --amend -massaged &&
 187        test_must_fail git push testrepo &&
 188        check_push_result $the_commit heads/master &&
 189        git reset --hard $the_commit
 190
 191'
 192
 193test_expect_success 'push --force with matching heads' '
 194
 195        mk_test heads/master &&
 196        git push testrepo : &&
 197        git commit --amend -massaged &&
 198        git push --force testrepo &&
 199        ! check_push_result $the_commit heads/master &&
 200        git reset --hard $the_commit
 201
 202'
 203
 204test_expect_success 'push with matching heads and forced update' '
 205
 206        mk_test heads/master &&
 207        git push testrepo : &&
 208        git commit --amend -massaged &&
 209        git push testrepo +: &&
 210        ! check_push_result $the_commit heads/master &&
 211        git reset --hard $the_commit
 212
 213'
 214
 215test_expect_success 'push with no ambiguity (1)' '
 216
 217        mk_test heads/master &&
 218        git push testrepo master:master &&
 219        check_push_result $the_commit heads/master
 220
 221'
 222
 223test_expect_success 'push with no ambiguity (2)' '
 224
 225        mk_test remotes/origin/master &&
 226        git push testrepo master:origin/master &&
 227        check_push_result $the_commit remotes/origin/master
 228
 229'
 230
 231test_expect_success 'push with colon-less refspec, no ambiguity' '
 232
 233        mk_test heads/master heads/t/master &&
 234        git branch -f t/master master &&
 235        git push testrepo master &&
 236        check_push_result $the_commit heads/master &&
 237        check_push_result $the_first_commit heads/t/master
 238
 239'
 240
 241test_expect_success 'push with weak ambiguity (1)' '
 242
 243        mk_test heads/master remotes/origin/master &&
 244        git push testrepo master:master &&
 245        check_push_result $the_commit heads/master &&
 246        check_push_result $the_first_commit remotes/origin/master
 247
 248'
 249
 250test_expect_success 'push with weak ambiguity (2)' '
 251
 252        mk_test heads/master remotes/origin/master remotes/another/master &&
 253        git push testrepo master:master &&
 254        check_push_result $the_commit heads/master &&
 255        check_push_result $the_first_commit remotes/origin/master remotes/another/master
 256
 257'
 258
 259test_expect_success 'push with ambiguity' '
 260
 261        mk_test heads/frotz tags/frotz &&
 262        if git push testrepo master:frotz
 263        then
 264                echo "Oops, should have failed"
 265                false
 266        else
 267                check_push_result $the_first_commit heads/frotz tags/frotz
 268        fi
 269
 270'
 271
 272test_expect_success 'push with colon-less refspec (1)' '
 273
 274        mk_test heads/frotz tags/frotz &&
 275        git branch -f frotz master &&
 276        git push testrepo frotz &&
 277        check_push_result $the_commit heads/frotz &&
 278        check_push_result $the_first_commit tags/frotz
 279
 280'
 281
 282test_expect_success 'push with colon-less refspec (2)' '
 283
 284        mk_test heads/frotz tags/frotz &&
 285        if git show-ref --verify -q refs/heads/frotz
 286        then
 287                git branch -D frotz
 288        fi &&
 289        git tag -f frotz &&
 290        git push testrepo frotz &&
 291        check_push_result $the_commit tags/frotz &&
 292        check_push_result $the_first_commit heads/frotz
 293
 294'
 295
 296test_expect_success 'push with colon-less refspec (3)' '
 297
 298        mk_test &&
 299        if git show-ref --verify -q refs/tags/frotz
 300        then
 301                git tag -d frotz
 302        fi &&
 303        git branch -f frotz master &&
 304        git push testrepo frotz &&
 305        check_push_result $the_commit heads/frotz &&
 306        test 1 = $( cd testrepo && git show-ref | wc -l )
 307'
 308
 309test_expect_success 'push with colon-less refspec (4)' '
 310
 311        mk_test &&
 312        if git show-ref --verify -q refs/heads/frotz
 313        then
 314                git branch -D frotz
 315        fi &&
 316        git tag -f frotz &&
 317        git push testrepo frotz &&
 318        check_push_result $the_commit tags/frotz &&
 319        test 1 = $( cd testrepo && git show-ref | wc -l )
 320
 321'
 322
 323test_expect_success 'push head with non-existant, incomplete dest' '
 324
 325        mk_test &&
 326        git push testrepo master:branch &&
 327        check_push_result $the_commit heads/branch
 328
 329'
 330
 331test_expect_success 'push tag with non-existant, incomplete dest' '
 332
 333        mk_test &&
 334        git tag -f v1.0 &&
 335        git push testrepo v1.0:tag &&
 336        check_push_result $the_commit tags/tag
 337
 338'
 339
 340test_expect_success 'push sha1 with non-existant, incomplete dest' '
 341
 342        mk_test &&
 343        test_must_fail git push testrepo `git rev-parse master`:foo
 344
 345'
 346
 347test_expect_success 'push ref expression with non-existant, incomplete dest' '
 348
 349        mk_test &&
 350        test_must_fail git push testrepo master^:branch
 351
 352'
 353
 354test_expect_success 'push with HEAD' '
 355
 356        mk_test heads/master &&
 357        git checkout master &&
 358        git push testrepo HEAD &&
 359        check_push_result $the_commit heads/master
 360
 361'
 362
 363test_expect_success 'push with HEAD nonexisting at remote' '
 364
 365        mk_test heads/master &&
 366        git checkout -b local master &&
 367        git push testrepo HEAD &&
 368        check_push_result $the_commit heads/local
 369'
 370
 371test_expect_success 'push with +HEAD' '
 372
 373        mk_test heads/master &&
 374        git checkout master &&
 375        git branch -D local &&
 376        git checkout -b local &&
 377        git push testrepo master local &&
 378        check_push_result $the_commit heads/master &&
 379        check_push_result $the_commit heads/local &&
 380
 381        # Without force rewinding should fail
 382        git reset --hard HEAD^ &&
 383        test_must_fail git push testrepo HEAD &&
 384        check_push_result $the_commit heads/local &&
 385
 386        # With force rewinding should succeed
 387        git push testrepo +HEAD &&
 388        check_push_result $the_first_commit heads/local
 389
 390'
 391
 392test_expect_success 'push HEAD with non-existant, incomplete dest' '
 393
 394        mk_test &&
 395        git checkout master &&
 396        git push testrepo HEAD:branch &&
 397        check_push_result $the_commit heads/branch
 398
 399'
 400
 401test_expect_success 'push with config remote.*.push = HEAD' '
 402
 403        mk_test heads/local &&
 404        git checkout master &&
 405        git branch -f local $the_commit &&
 406        (
 407                cd testrepo &&
 408                git checkout local &&
 409                git reset --hard $the_first_commit
 410        ) &&
 411        git config remote.there.url testrepo &&
 412        git config remote.there.push HEAD &&
 413        git config branch.master.remote there &&
 414        git push &&
 415        check_push_result $the_commit heads/master &&
 416        check_push_result $the_first_commit heads/local
 417'
 418
 419# clean up the cruft left with the previous one
 420git config --remove-section remote.there
 421git config --remove-section branch.master
 422
 423test_expect_success 'push with config remote.*.pushurl' '
 424
 425        mk_test heads/master &&
 426        git checkout master &&
 427        git config remote.there.url test2repo &&
 428        git config remote.there.pushurl testrepo &&
 429        git push there &&
 430        check_push_result $the_commit heads/master
 431'
 432
 433# clean up the cruft left with the previous one
 434git config --remove-section remote.there
 435
 436test_expect_success 'push with dry-run' '
 437
 438        mk_test heads/master &&
 439        (cd testrepo &&
 440         old_commit=$(git show-ref -s --verify refs/heads/master)) &&
 441        git push --dry-run testrepo &&
 442        check_push_result $old_commit heads/master
 443'
 444
 445test_expect_success 'push updates local refs' '
 446
 447        mk_test heads/master &&
 448        mk_child child &&
 449        (cd child &&
 450                git pull .. master &&
 451                git push &&
 452        test $(git rev-parse master) = $(git rev-parse remotes/origin/master))
 453
 454'
 455
 456test_expect_success 'push updates up-to-date local refs' '
 457
 458        mk_test heads/master &&
 459        mk_child child1 &&
 460        mk_child child2 &&
 461        (cd child1 && git pull .. master && git push) &&
 462        (cd child2 &&
 463                git pull ../child1 master &&
 464                git push &&
 465        test $(git rev-parse master) = $(git rev-parse remotes/origin/master))
 466
 467'
 468
 469test_expect_success 'push preserves up-to-date packed refs' '
 470
 471        mk_test heads/master &&
 472        mk_child child &&
 473        (cd child &&
 474                git push &&
 475        ! test -f .git/refs/remotes/origin/master)
 476
 477'
 478
 479test_expect_success 'push does not update local refs on failure' '
 480
 481        mk_test heads/master &&
 482        mk_child child &&
 483        mkdir testrepo/.git/hooks &&
 484        echo exit 1 >testrepo/.git/hooks/pre-receive &&
 485        chmod +x testrepo/.git/hooks/pre-receive &&
 486        (cd child &&
 487                git pull .. master
 488                test_must_fail git push &&
 489                test $(git rev-parse master) != \
 490                        $(git rev-parse remotes/origin/master))
 491
 492'
 493
 494test_expect_success 'allow deleting an invalid remote ref' '
 495
 496        mk_test heads/master &&
 497        rm -f testrepo/.git/objects/??/* &&
 498        git push testrepo :refs/heads/master &&
 499        (cd testrepo && test_must_fail git rev-parse --verify refs/heads/master)
 500
 501'
 502
 503test_expect_success 'warn on push to HEAD of non-bare repository' '
 504        mk_test heads/master
 505        (cd testrepo &&
 506                git checkout master &&
 507                git config receive.denyCurrentBranch warn) &&
 508        git push testrepo master 2>stderr &&
 509        grep "warning: updating the current branch" stderr
 510'
 511
 512test_expect_success 'deny push to HEAD of non-bare repository' '
 513        mk_test heads/master
 514        (cd testrepo &&
 515                git checkout master &&
 516                git config receive.denyCurrentBranch true) &&
 517        test_must_fail git push testrepo master
 518'
 519
 520test_expect_success 'allow push to HEAD of bare repository (bare)' '
 521        mk_test heads/master
 522        (cd testrepo &&
 523                git checkout master &&
 524                git config receive.denyCurrentBranch true &&
 525                git config core.bare true) &&
 526        git push testrepo master 2>stderr &&
 527        ! grep "warning: updating the current branch" stderr
 528'
 529
 530test_expect_success 'allow push to HEAD of non-bare repository (config)' '
 531        mk_test heads/master
 532        (cd testrepo &&
 533                git checkout master &&
 534                git config receive.denyCurrentBranch false
 535        ) &&
 536        git push testrepo master 2>stderr &&
 537        ! grep "warning: updating the current branch" stderr
 538'
 539
 540test_expect_success 'fetch with branches' '
 541        mk_empty &&
 542        git branch second $the_first_commit &&
 543        git checkout second &&
 544        echo ".." > testrepo/.git/branches/branch1 &&
 545        (cd testrepo &&
 546                git fetch branch1 &&
 547                r=$(git show-ref -s --verify refs/heads/branch1) &&
 548                test "z$r" = "z$the_commit" &&
 549                test 1 = $(git for-each-ref refs/heads | wc -l)
 550        ) &&
 551        git checkout master
 552'
 553
 554test_expect_success 'fetch with branches containing #' '
 555        mk_empty &&
 556        echo "..#second" > testrepo/.git/branches/branch2 &&
 557        (cd testrepo &&
 558                git fetch branch2 &&
 559                r=$(git show-ref -s --verify refs/heads/branch2) &&
 560                test "z$r" = "z$the_first_commit" &&
 561                test 1 = $(git for-each-ref refs/heads | wc -l)
 562        ) &&
 563        git checkout master
 564'
 565
 566test_expect_success 'push with branches' '
 567        mk_empty &&
 568        git checkout second &&
 569        echo "testrepo" > .git/branches/branch1 &&
 570        git push branch1 &&
 571        (cd testrepo &&
 572                r=$(git show-ref -s --verify refs/heads/master) &&
 573                test "z$r" = "z$the_first_commit" &&
 574                test 1 = $(git for-each-ref refs/heads | wc -l)
 575        )
 576'
 577
 578test_expect_success 'push with branches containing #' '
 579        mk_empty &&
 580        echo "testrepo#branch3" > .git/branches/branch2 &&
 581        git push branch2 &&
 582        (cd testrepo &&
 583                r=$(git show-ref -s --verify refs/heads/branch3) &&
 584                test "z$r" = "z$the_first_commit" &&
 585                test 1 = $(git for-each-ref refs/heads | wc -l)
 586        ) &&
 587        git checkout master
 588'
 589
 590test_done