t / t5516-fetch-push.shon commit Merge branch 'rs/sort-oid-array-thread-safe' (2743b61)
   1#!/bin/sh
   2
   3test_description='Basic fetch/push functionality.
   4
   5This test checks the following functionality:
   6
   7* command-line syntax
   8* refspecs
   9* fast-forward detection, and overriding it
  10* configuration
  11* hooks
  12* --porcelain output format
  13* hiderefs
  14* reflogs
  15'
  16
  17. ./test-lib.sh
  18
  19D=$(pwd)
  20
  21mk_empty () {
  22        repo_name="$1"
  23        rm -fr "$repo_name" &&
  24        mkdir "$repo_name" &&
  25        (
  26                cd "$repo_name" &&
  27                git init &&
  28                git config receive.denyCurrentBranch warn &&
  29                mv .git/hooks .git/hooks-disabled
  30        )
  31}
  32
  33mk_test () {
  34        repo_name="$1"
  35        shift
  36
  37        mk_empty "$repo_name" &&
  38        (
  39                for ref in "$@"
  40                do
  41                        git push "$repo_name" $the_first_commit:refs/$ref ||
  42                        exit
  43                done &&
  44                cd "$repo_name" &&
  45                for ref in "$@"
  46                do
  47                        echo "$the_first_commit" >expect &&
  48                        git show-ref -s --verify refs/$ref >actual &&
  49                        test_cmp expect actual ||
  50                        exit
  51                done &&
  52                git fsck --full
  53        )
  54}
  55
  56mk_test_with_hooks() {
  57        repo_name=$1
  58        mk_test "$@" &&
  59        (
  60                cd "$repo_name" &&
  61                mkdir .git/hooks &&
  62                cd .git/hooks &&
  63
  64                cat >pre-receive <<-'EOF' &&
  65                #!/bin/sh
  66                cat - >>pre-receive.actual
  67                EOF
  68
  69                cat >update <<-'EOF' &&
  70                #!/bin/sh
  71                printf "%s %s %s\n" "$@" >>update.actual
  72                EOF
  73
  74                cat >post-receive <<-'EOF' &&
  75                #!/bin/sh
  76                cat - >>post-receive.actual
  77                EOF
  78
  79                cat >post-update <<-'EOF' &&
  80                #!/bin/sh
  81                for ref in "$@"
  82                do
  83                        printf "%s\n" "$ref" >>post-update.actual
  84                done
  85                EOF
  86
  87                chmod +x pre-receive update post-receive post-update
  88        )
  89}
  90
  91mk_child() {
  92        rm -rf "$2" &&
  93        git clone "$1" "$2"
  94}
  95
  96check_push_result () {
  97        test $# -ge 3 ||
  98        BUG "check_push_result requires at least 3 parameters"
  99
 100        repo_name="$1"
 101        shift
 102
 103        (
 104                cd "$repo_name" &&
 105                echo "$1" >expect &&
 106                shift &&
 107                for ref in "$@"
 108                do
 109                        git show-ref -s --verify refs/$ref >actual &&
 110                        test_cmp expect actual ||
 111                        exit
 112                done &&
 113                git fsck --full
 114        )
 115}
 116
 117test_expect_success setup '
 118
 119        >path1 &&
 120        git add path1 &&
 121        test_tick &&
 122        git commit -a -m repo &&
 123        the_first_commit=$(git show-ref -s --verify refs/heads/master) &&
 124
 125        >path2 &&
 126        git add path2 &&
 127        test_tick &&
 128        git commit -a -m second &&
 129        the_commit=$(git show-ref -s --verify refs/heads/master)
 130
 131'
 132
 133test_expect_success 'fetch without wildcard' '
 134        mk_empty testrepo &&
 135        (
 136                cd testrepo &&
 137                git fetch .. refs/heads/master:refs/remotes/origin/master &&
 138
 139                echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 140                git for-each-ref refs/remotes/origin >actual &&
 141                test_cmp expect actual
 142        )
 143'
 144
 145test_expect_success 'fetch with wildcard' '
 146        mk_empty testrepo &&
 147        (
 148                cd testrepo &&
 149                git config remote.up.url .. &&
 150                git config remote.up.fetch "refs/heads/*:refs/remotes/origin/*" &&
 151                git fetch up &&
 152
 153                echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 154                git for-each-ref refs/remotes/origin >actual &&
 155                test_cmp expect actual
 156        )
 157'
 158
 159test_expect_success 'fetch with insteadOf' '
 160        mk_empty testrepo &&
 161        (
 162                TRASH=$(pwd)/ &&
 163                cd testrepo &&
 164                git config "url.$TRASH.insteadOf" trash/ &&
 165                git config remote.up.url trash/. &&
 166                git config remote.up.fetch "refs/heads/*:refs/remotes/origin/*" &&
 167                git fetch up &&
 168
 169                echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 170                git for-each-ref refs/remotes/origin >actual &&
 171                test_cmp expect actual
 172        )
 173'
 174
 175test_expect_success 'fetch with pushInsteadOf (should not rewrite)' '
 176        mk_empty testrepo &&
 177        (
 178                TRASH=$(pwd)/ &&
 179                cd testrepo &&
 180                git config "url.trash/.pushInsteadOf" "$TRASH" &&
 181                git config remote.up.url "$TRASH." &&
 182                git config remote.up.fetch "refs/heads/*:refs/remotes/origin/*" &&
 183                git fetch up &&
 184
 185                echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 186                git for-each-ref refs/remotes/origin >actual &&
 187                test_cmp expect actual
 188        )
 189'
 190
 191test_expect_success 'push without wildcard' '
 192        mk_empty testrepo &&
 193
 194        git push testrepo refs/heads/master:refs/remotes/origin/master &&
 195        (
 196                cd testrepo &&
 197                echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 198                git for-each-ref refs/remotes/origin >actual &&
 199                test_cmp expect actual
 200        )
 201'
 202
 203test_expect_success 'push with wildcard' '
 204        mk_empty testrepo &&
 205
 206        git push testrepo "refs/heads/*:refs/remotes/origin/*" &&
 207        (
 208                cd testrepo &&
 209                echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 210                git for-each-ref refs/remotes/origin >actual &&
 211                test_cmp expect actual
 212        )
 213'
 214
 215test_expect_success 'push with insteadOf' '
 216        mk_empty testrepo &&
 217        TRASH="$(pwd)/" &&
 218        test_config "url.$TRASH.insteadOf" trash/ &&
 219        git push trash/testrepo refs/heads/master:refs/remotes/origin/master &&
 220        (
 221                cd testrepo &&
 222                echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 223                git for-each-ref refs/remotes/origin >actual &&
 224                test_cmp expect actual
 225        )
 226'
 227
 228test_expect_success 'push with pushInsteadOf' '
 229        mk_empty testrepo &&
 230        TRASH="$(pwd)/" &&
 231        test_config "url.$TRASH.pushInsteadOf" trash/ &&
 232        git push trash/testrepo refs/heads/master:refs/remotes/origin/master &&
 233        (
 234                cd testrepo &&
 235                echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 236                git for-each-ref refs/remotes/origin >actual &&
 237                test_cmp expect actual
 238        )
 239'
 240
 241test_expect_success 'push with pushInsteadOf and explicit pushurl (pushInsteadOf should not rewrite)' '
 242        mk_empty testrepo &&
 243        test_config "url.trash2/.pushInsteadOf" testrepo/ &&
 244        test_config "url.trash3/.pushInsteadOf" trash/wrong &&
 245        test_config remote.r.url trash/wrong &&
 246        test_config remote.r.pushurl "testrepo/" &&
 247        git push r refs/heads/master:refs/remotes/origin/master &&
 248        (
 249                cd testrepo &&
 250                echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 251                git for-each-ref refs/remotes/origin >actual &&
 252                test_cmp expect actual
 253        )
 254'
 255
 256test_expect_success 'push with matching heads' '
 257
 258        mk_test testrepo heads/master &&
 259        git push testrepo : &&
 260        check_push_result testrepo $the_commit heads/master
 261
 262'
 263
 264test_expect_success 'push with matching heads on the command line' '
 265
 266        mk_test testrepo heads/master &&
 267        git push testrepo : &&
 268        check_push_result testrepo $the_commit heads/master
 269
 270'
 271
 272test_expect_success 'failed (non-fast-forward) push with matching heads' '
 273
 274        mk_test testrepo heads/master &&
 275        git push testrepo : &&
 276        git commit --amend -massaged &&
 277        test_must_fail git push testrepo &&
 278        check_push_result testrepo $the_commit heads/master &&
 279        git reset --hard $the_commit
 280
 281'
 282
 283test_expect_success 'push --force with matching heads' '
 284
 285        mk_test testrepo heads/master &&
 286        git push testrepo : &&
 287        git commit --amend -massaged &&
 288        git push --force testrepo : &&
 289        ! check_push_result testrepo $the_commit heads/master &&
 290        git reset --hard $the_commit
 291
 292'
 293
 294test_expect_success 'push with matching heads and forced update' '
 295
 296        mk_test testrepo heads/master &&
 297        git push testrepo : &&
 298        git commit --amend -massaged &&
 299        git push testrepo +: &&
 300        ! check_push_result testrepo $the_commit heads/master &&
 301        git reset --hard $the_commit
 302
 303'
 304
 305test_expect_success 'push with no ambiguity (1)' '
 306
 307        mk_test testrepo heads/master &&
 308        git push testrepo master:master &&
 309        check_push_result testrepo $the_commit heads/master
 310
 311'
 312
 313test_expect_success 'push with no ambiguity (2)' '
 314
 315        mk_test testrepo remotes/origin/master &&
 316        git push testrepo master:origin/master &&
 317        check_push_result testrepo $the_commit remotes/origin/master
 318
 319'
 320
 321test_expect_success 'push with colon-less refspec, no ambiguity' '
 322
 323        mk_test testrepo heads/master heads/t/master &&
 324        git branch -f t/master master &&
 325        git push testrepo master &&
 326        check_push_result testrepo $the_commit heads/master &&
 327        check_push_result testrepo $the_first_commit heads/t/master
 328
 329'
 330
 331test_expect_success 'push with weak ambiguity (1)' '
 332
 333        mk_test testrepo heads/master remotes/origin/master &&
 334        git push testrepo master:master &&
 335        check_push_result testrepo $the_commit heads/master &&
 336        check_push_result testrepo $the_first_commit remotes/origin/master
 337
 338'
 339
 340test_expect_success 'push with weak ambiguity (2)' '
 341
 342        mk_test testrepo heads/master remotes/origin/master remotes/another/master &&
 343        git push testrepo master:master &&
 344        check_push_result testrepo $the_commit heads/master &&
 345        check_push_result testrepo $the_first_commit remotes/origin/master remotes/another/master
 346
 347'
 348
 349test_expect_success 'push with ambiguity' '
 350
 351        mk_test testrepo heads/frotz tags/frotz &&
 352        test_must_fail git push testrepo master:frotz &&
 353        check_push_result testrepo $the_first_commit heads/frotz tags/frotz
 354
 355'
 356
 357test_expect_success 'push with colon-less refspec (1)' '
 358
 359        mk_test testrepo heads/frotz tags/frotz &&
 360        git branch -f frotz master &&
 361        git push testrepo frotz &&
 362        check_push_result testrepo $the_commit heads/frotz &&
 363        check_push_result testrepo $the_first_commit tags/frotz
 364
 365'
 366
 367test_expect_success 'push with colon-less refspec (2)' '
 368
 369        mk_test testrepo heads/frotz tags/frotz &&
 370        if git show-ref --verify -q refs/heads/frotz
 371        then
 372                git branch -D frotz
 373        fi &&
 374        git tag -f frotz &&
 375        git push -f testrepo frotz &&
 376        check_push_result testrepo $the_commit tags/frotz &&
 377        check_push_result testrepo $the_first_commit heads/frotz
 378
 379'
 380
 381test_expect_success 'push with colon-less refspec (3)' '
 382
 383        mk_test testrepo &&
 384        if git show-ref --verify -q refs/tags/frotz
 385        then
 386                git tag -d frotz
 387        fi &&
 388        git branch -f frotz master &&
 389        git push testrepo frotz &&
 390        check_push_result testrepo $the_commit heads/frotz &&
 391        test 1 = $( cd testrepo && git show-ref | wc -l )
 392'
 393
 394test_expect_success 'push with colon-less refspec (4)' '
 395
 396        mk_test testrepo &&
 397        if git show-ref --verify -q refs/heads/frotz
 398        then
 399                git branch -D frotz
 400        fi &&
 401        git tag -f frotz &&
 402        git push testrepo frotz &&
 403        check_push_result testrepo $the_commit tags/frotz &&
 404        test 1 = $( cd testrepo && git show-ref | wc -l )
 405
 406'
 407
 408test_expect_success 'push head with non-existent, incomplete dest' '
 409
 410        mk_test testrepo &&
 411        git push testrepo master:branch &&
 412        check_push_result testrepo $the_commit heads/branch
 413
 414'
 415
 416test_expect_success 'push tag with non-existent, incomplete dest' '
 417
 418        mk_test testrepo &&
 419        git tag -f v1.0 &&
 420        git push testrepo v1.0:tag &&
 421        check_push_result testrepo $the_commit tags/tag
 422
 423'
 424
 425test_expect_success 'push sha1 with non-existent, incomplete dest' '
 426
 427        mk_test testrepo &&
 428        test_must_fail git push testrepo $(git rev-parse master):foo
 429
 430'
 431
 432test_expect_success 'push ref expression with non-existent, incomplete dest' '
 433
 434        mk_test testrepo &&
 435        test_must_fail git push testrepo master^:branch
 436
 437'
 438
 439test_expect_success 'push with HEAD' '
 440
 441        mk_test testrepo heads/master &&
 442        git checkout master &&
 443        git push testrepo HEAD &&
 444        check_push_result testrepo $the_commit heads/master
 445
 446'
 447
 448test_expect_success 'push with HEAD nonexisting at remote' '
 449
 450        mk_test testrepo heads/master &&
 451        git checkout -b local master &&
 452        git push testrepo HEAD &&
 453        check_push_result testrepo $the_commit heads/local
 454'
 455
 456test_expect_success 'push with +HEAD' '
 457
 458        mk_test testrepo heads/master &&
 459        git checkout master &&
 460        git branch -D local &&
 461        git checkout -b local &&
 462        git push testrepo master local &&
 463        check_push_result testrepo $the_commit heads/master &&
 464        check_push_result testrepo $the_commit heads/local &&
 465
 466        # Without force rewinding should fail
 467        git reset --hard HEAD^ &&
 468        test_must_fail git push testrepo HEAD &&
 469        check_push_result testrepo $the_commit heads/local &&
 470
 471        # With force rewinding should succeed
 472        git push testrepo +HEAD &&
 473        check_push_result testrepo $the_first_commit heads/local
 474
 475'
 476
 477test_expect_success 'push HEAD with non-existent, incomplete dest' '
 478
 479        mk_test testrepo &&
 480        git checkout master &&
 481        git push testrepo HEAD:branch &&
 482        check_push_result testrepo $the_commit heads/branch
 483
 484'
 485
 486test_expect_success 'push with config remote.*.push = HEAD' '
 487
 488        mk_test testrepo heads/local &&
 489        git checkout master &&
 490        git branch -f local $the_commit &&
 491        (
 492                cd testrepo &&
 493                git checkout local &&
 494                git reset --hard $the_first_commit
 495        ) &&
 496        test_config remote.there.url testrepo &&
 497        test_config remote.there.push HEAD &&
 498        test_config branch.master.remote there &&
 499        git push &&
 500        check_push_result testrepo $the_commit heads/master &&
 501        check_push_result testrepo $the_first_commit heads/local
 502'
 503
 504test_expect_success 'push with remote.pushdefault' '
 505        mk_test up_repo heads/master &&
 506        mk_test down_repo heads/master &&
 507        test_config remote.up.url up_repo &&
 508        test_config remote.down.url down_repo &&
 509        test_config branch.master.remote up &&
 510        test_config remote.pushdefault down &&
 511        test_config push.default matching &&
 512        git push &&
 513        check_push_result up_repo $the_first_commit heads/master &&
 514        check_push_result down_repo $the_commit heads/master
 515'
 516
 517test_expect_success 'push with config remote.*.pushurl' '
 518
 519        mk_test testrepo heads/master &&
 520        git checkout master &&
 521        test_config remote.there.url test2repo &&
 522        test_config remote.there.pushurl testrepo &&
 523        git push there : &&
 524        check_push_result testrepo $the_commit heads/master
 525'
 526
 527test_expect_success 'push with config branch.*.pushremote' '
 528        mk_test up_repo heads/master &&
 529        mk_test side_repo heads/master &&
 530        mk_test down_repo heads/master &&
 531        test_config remote.up.url up_repo &&
 532        test_config remote.pushdefault side_repo &&
 533        test_config remote.down.url down_repo &&
 534        test_config branch.master.remote up &&
 535        test_config branch.master.pushremote down &&
 536        test_config push.default matching &&
 537        git push &&
 538        check_push_result up_repo $the_first_commit heads/master &&
 539        check_push_result side_repo $the_first_commit heads/master &&
 540        check_push_result down_repo $the_commit heads/master
 541'
 542
 543test_expect_success 'branch.*.pushremote config order is irrelevant' '
 544        mk_test one_repo heads/master &&
 545        mk_test two_repo heads/master &&
 546        test_config remote.one.url one_repo &&
 547        test_config remote.two.url two_repo &&
 548        test_config branch.master.pushremote two_repo &&
 549        test_config remote.pushdefault one_repo &&
 550        test_config push.default matching &&
 551        git push &&
 552        check_push_result one_repo $the_first_commit heads/master &&
 553        check_push_result two_repo $the_commit heads/master
 554'
 555
 556test_expect_success 'push with dry-run' '
 557
 558        mk_test testrepo heads/master &&
 559        old_commit=$(git -C testrepo show-ref -s --verify refs/heads/master) &&
 560        git push --dry-run testrepo : &&
 561        check_push_result testrepo $old_commit heads/master
 562'
 563
 564test_expect_success 'push updates local refs' '
 565
 566        mk_test testrepo heads/master &&
 567        mk_child testrepo child &&
 568        (
 569                cd child &&
 570                git pull .. master &&
 571                git push &&
 572                test $(git rev-parse master) = \
 573                        $(git rev-parse remotes/origin/master)
 574        )
 575
 576'
 577
 578test_expect_success 'push updates up-to-date local refs' '
 579
 580        mk_test testrepo heads/master &&
 581        mk_child testrepo child1 &&
 582        mk_child testrepo child2 &&
 583        (cd child1 && git pull .. master && git push) &&
 584        (
 585                cd child2 &&
 586                git pull ../child1 master &&
 587                git push &&
 588                test $(git rev-parse master) = \
 589                        $(git rev-parse remotes/origin/master)
 590        )
 591
 592'
 593
 594test_expect_success 'push preserves up-to-date packed refs' '
 595
 596        mk_test testrepo heads/master &&
 597        mk_child testrepo child &&
 598        (
 599                cd child &&
 600                git push &&
 601                ! test -f .git/refs/remotes/origin/master
 602        )
 603
 604'
 605
 606test_expect_success 'push does not update local refs on failure' '
 607
 608        mk_test testrepo heads/master &&
 609        mk_child testrepo child &&
 610        mkdir testrepo/.git/hooks &&
 611        echo "#!/no/frobnication/today" >testrepo/.git/hooks/pre-receive &&
 612        chmod +x testrepo/.git/hooks/pre-receive &&
 613        (
 614                cd child &&
 615                git pull .. master &&
 616                test_must_fail git push &&
 617                test $(git rev-parse master) != \
 618                        $(git rev-parse remotes/origin/master)
 619        )
 620
 621'
 622
 623test_expect_success 'allow deleting an invalid remote ref' '
 624
 625        mk_test testrepo heads/master &&
 626        rm -f testrepo/.git/objects/??/* &&
 627        git push testrepo :refs/heads/master &&
 628        (cd testrepo && test_must_fail git rev-parse --verify refs/heads/master)
 629
 630'
 631
 632test_expect_success 'pushing valid refs triggers post-receive and post-update hooks' '
 633        mk_test_with_hooks testrepo heads/master heads/next &&
 634        orgmaster=$(cd testrepo && git show-ref -s --verify refs/heads/master) &&
 635        newmaster=$(git show-ref -s --verify refs/heads/master) &&
 636        orgnext=$(cd testrepo && git show-ref -s --verify refs/heads/next) &&
 637        newnext=$ZERO_OID &&
 638        git push testrepo refs/heads/master:refs/heads/master :refs/heads/next &&
 639        (
 640                cd testrepo/.git &&
 641                cat >pre-receive.expect <<-EOF &&
 642                $orgmaster $newmaster refs/heads/master
 643                $orgnext $newnext refs/heads/next
 644                EOF
 645
 646                cat >update.expect <<-EOF &&
 647                refs/heads/master $orgmaster $newmaster
 648                refs/heads/next $orgnext $newnext
 649                EOF
 650
 651                cat >post-receive.expect <<-EOF &&
 652                $orgmaster $newmaster refs/heads/master
 653                $orgnext $newnext refs/heads/next
 654                EOF
 655
 656                cat >post-update.expect <<-EOF &&
 657                refs/heads/master
 658                refs/heads/next
 659                EOF
 660
 661                test_cmp pre-receive.expect pre-receive.actual &&
 662                test_cmp update.expect update.actual &&
 663                test_cmp post-receive.expect post-receive.actual &&
 664                test_cmp post-update.expect post-update.actual
 665        )
 666'
 667
 668test_expect_success 'deleting dangling ref triggers hooks with correct args' '
 669        mk_test_with_hooks testrepo heads/master &&
 670        rm -f testrepo/.git/objects/??/* &&
 671        git push testrepo :refs/heads/master &&
 672        (
 673                cd testrepo/.git &&
 674                cat >pre-receive.expect <<-EOF &&
 675                $ZERO_OID $ZERO_OID refs/heads/master
 676                EOF
 677
 678                cat >update.expect <<-EOF &&
 679                refs/heads/master $ZERO_OID $ZERO_OID
 680                EOF
 681
 682                cat >post-receive.expect <<-EOF &&
 683                $ZERO_OID $ZERO_OID refs/heads/master
 684                EOF
 685
 686                cat >post-update.expect <<-EOF &&
 687                refs/heads/master
 688                EOF
 689
 690                test_cmp pre-receive.expect pre-receive.actual &&
 691                test_cmp update.expect update.actual &&
 692                test_cmp post-receive.expect post-receive.actual &&
 693                test_cmp post-update.expect post-update.actual
 694        )
 695'
 696
 697test_expect_success 'deletion of a non-existent ref is not fed to post-receive and post-update hooks' '
 698        mk_test_with_hooks testrepo heads/master &&
 699        orgmaster=$(cd testrepo && git show-ref -s --verify refs/heads/master) &&
 700        newmaster=$(git show-ref -s --verify refs/heads/master) &&
 701        git push testrepo master :refs/heads/nonexistent &&
 702        (
 703                cd testrepo/.git &&
 704                cat >pre-receive.expect <<-EOF &&
 705                $orgmaster $newmaster refs/heads/master
 706                $ZERO_OID $ZERO_OID refs/heads/nonexistent
 707                EOF
 708
 709                cat >update.expect <<-EOF &&
 710                refs/heads/master $orgmaster $newmaster
 711                refs/heads/nonexistent $ZERO_OID $ZERO_OID
 712                EOF
 713
 714                cat >post-receive.expect <<-EOF &&
 715                $orgmaster $newmaster refs/heads/master
 716                EOF
 717
 718                cat >post-update.expect <<-EOF &&
 719                refs/heads/master
 720                EOF
 721
 722                test_cmp pre-receive.expect pre-receive.actual &&
 723                test_cmp update.expect update.actual &&
 724                test_cmp post-receive.expect post-receive.actual &&
 725                test_cmp post-update.expect post-update.actual
 726        )
 727'
 728
 729test_expect_success 'deletion of a non-existent ref alone does trigger post-receive and post-update hooks' '
 730        mk_test_with_hooks testrepo heads/master &&
 731        git push testrepo :refs/heads/nonexistent &&
 732        (
 733                cd testrepo/.git &&
 734                cat >pre-receive.expect <<-EOF &&
 735                $ZERO_OID $ZERO_OID refs/heads/nonexistent
 736                EOF
 737
 738                cat >update.expect <<-EOF &&
 739                refs/heads/nonexistent $ZERO_OID $ZERO_OID
 740                EOF
 741
 742                test_cmp pre-receive.expect pre-receive.actual &&
 743                test_cmp update.expect update.actual &&
 744                test_path_is_missing post-receive.actual &&
 745                test_path_is_missing post-update.actual
 746        )
 747'
 748
 749test_expect_success 'mixed ref updates, deletes, invalid deletes trigger hooks with correct input' '
 750        mk_test_with_hooks testrepo heads/master heads/next heads/pu &&
 751        orgmaster=$(cd testrepo && git show-ref -s --verify refs/heads/master) &&
 752        newmaster=$(git show-ref -s --verify refs/heads/master) &&
 753        orgnext=$(cd testrepo && git show-ref -s --verify refs/heads/next) &&
 754        newnext=$ZERO_OID &&
 755        orgpu=$(cd testrepo && git show-ref -s --verify refs/heads/pu) &&
 756        newpu=$(git show-ref -s --verify refs/heads/master) &&
 757        git push testrepo refs/heads/master:refs/heads/master \
 758            refs/heads/master:refs/heads/pu :refs/heads/next \
 759            :refs/heads/nonexistent &&
 760        (
 761                cd testrepo/.git &&
 762                cat >pre-receive.expect <<-EOF &&
 763                $orgmaster $newmaster refs/heads/master
 764                $orgnext $newnext refs/heads/next
 765                $orgpu $newpu refs/heads/pu
 766                $ZERO_OID $ZERO_OID refs/heads/nonexistent
 767                EOF
 768
 769                cat >update.expect <<-EOF &&
 770                refs/heads/master $orgmaster $newmaster
 771                refs/heads/next $orgnext $newnext
 772                refs/heads/pu $orgpu $newpu
 773                refs/heads/nonexistent $ZERO_OID $ZERO_OID
 774                EOF
 775
 776                cat >post-receive.expect <<-EOF &&
 777                $orgmaster $newmaster refs/heads/master
 778                $orgnext $newnext refs/heads/next
 779                $orgpu $newpu refs/heads/pu
 780                EOF
 781
 782                cat >post-update.expect <<-EOF &&
 783                refs/heads/master
 784                refs/heads/next
 785                refs/heads/pu
 786                EOF
 787
 788                test_cmp pre-receive.expect pre-receive.actual &&
 789                test_cmp update.expect update.actual &&
 790                test_cmp post-receive.expect post-receive.actual &&
 791                test_cmp post-update.expect post-update.actual
 792        )
 793'
 794
 795test_expect_success 'allow deleting a ref using --delete' '
 796        mk_test testrepo heads/master &&
 797        (cd testrepo && git config receive.denyDeleteCurrent warn) &&
 798        git push testrepo --delete master &&
 799        (cd testrepo && test_must_fail git rev-parse --verify refs/heads/master)
 800'
 801
 802test_expect_success 'allow deleting a tag using --delete' '
 803        mk_test testrepo heads/master &&
 804        git tag -a -m dummy_message deltag heads/master &&
 805        git push testrepo --tags &&
 806        (cd testrepo && git rev-parse --verify -q refs/tags/deltag) &&
 807        git push testrepo --delete tag deltag &&
 808        (cd testrepo && test_must_fail git rev-parse --verify refs/tags/deltag)
 809'
 810
 811test_expect_success 'push --delete without args aborts' '
 812        mk_test testrepo heads/master &&
 813        test_must_fail git push testrepo --delete
 814'
 815
 816test_expect_success 'push --delete refuses src:dest refspecs' '
 817        mk_test testrepo heads/master &&
 818        test_must_fail git push testrepo --delete master:foo
 819'
 820
 821test_expect_success 'warn on push to HEAD of non-bare repository' '
 822        mk_test testrepo heads/master &&
 823        (
 824                cd testrepo &&
 825                git checkout master &&
 826                git config receive.denyCurrentBranch warn
 827        ) &&
 828        git push testrepo master 2>stderr &&
 829        grep "warning: updating the current branch" stderr
 830'
 831
 832test_expect_success 'deny push to HEAD of non-bare repository' '
 833        mk_test testrepo heads/master &&
 834        (
 835                cd testrepo &&
 836                git checkout master &&
 837                git config receive.denyCurrentBranch true
 838        ) &&
 839        test_must_fail git push testrepo master
 840'
 841
 842test_expect_success 'allow push to HEAD of bare repository (bare)' '
 843        mk_test testrepo heads/master &&
 844        (
 845                cd testrepo &&
 846                git checkout master &&
 847                git config receive.denyCurrentBranch true &&
 848                git config core.bare true
 849        ) &&
 850        git push testrepo master 2>stderr &&
 851        ! grep "warning: updating the current branch" stderr
 852'
 853
 854test_expect_success 'allow push to HEAD of non-bare repository (config)' '
 855        mk_test testrepo heads/master &&
 856        (
 857                cd testrepo &&
 858                git checkout master &&
 859                git config receive.denyCurrentBranch false
 860        ) &&
 861        git push testrepo master 2>stderr &&
 862        ! grep "warning: updating the current branch" stderr
 863'
 864
 865test_expect_success 'fetch with branches' '
 866        mk_empty testrepo &&
 867        git branch second $the_first_commit &&
 868        git checkout second &&
 869        echo ".." > testrepo/.git/branches/branch1 &&
 870        (
 871                cd testrepo &&
 872                git fetch branch1 &&
 873                echo "$the_commit commit        refs/heads/branch1" >expect &&
 874                git for-each-ref refs/heads >actual &&
 875                test_cmp expect actual
 876        ) &&
 877        git checkout master
 878'
 879
 880test_expect_success 'fetch with branches containing #' '
 881        mk_empty testrepo &&
 882        echo "..#second" > testrepo/.git/branches/branch2 &&
 883        (
 884                cd testrepo &&
 885                git fetch branch2 &&
 886                echo "$the_first_commit commit  refs/heads/branch2" >expect &&
 887                git for-each-ref refs/heads >actual &&
 888                test_cmp expect actual
 889        ) &&
 890        git checkout master
 891'
 892
 893test_expect_success 'push with branches' '
 894        mk_empty testrepo &&
 895        git checkout second &&
 896        echo "testrepo" > .git/branches/branch1 &&
 897        git push branch1 &&
 898        (
 899                cd testrepo &&
 900                echo "$the_first_commit commit  refs/heads/master" >expect &&
 901                git for-each-ref refs/heads >actual &&
 902                test_cmp expect actual
 903        )
 904'
 905
 906test_expect_success 'push with branches containing #' '
 907        mk_empty testrepo &&
 908        echo "testrepo#branch3" > .git/branches/branch2 &&
 909        git push branch2 &&
 910        (
 911                cd testrepo &&
 912                echo "$the_first_commit commit  refs/heads/branch3" >expect &&
 913                git for-each-ref refs/heads >actual &&
 914                test_cmp expect actual
 915        ) &&
 916        git checkout master
 917'
 918
 919test_expect_success 'push into aliased refs (consistent)' '
 920        mk_test testrepo heads/master &&
 921        mk_child testrepo child1 &&
 922        mk_child testrepo child2 &&
 923        (
 924                cd child1 &&
 925                git branch foo &&
 926                git symbolic-ref refs/heads/bar refs/heads/foo &&
 927                git config receive.denyCurrentBranch false
 928        ) &&
 929        (
 930                cd child2 &&
 931                >path2 &&
 932                git add path2 &&
 933                test_tick &&
 934                git commit -a -m child2 &&
 935                git branch foo &&
 936                git branch bar &&
 937                git push ../child1 foo bar
 938        )
 939'
 940
 941test_expect_success 'push into aliased refs (inconsistent)' '
 942        mk_test testrepo heads/master &&
 943        mk_child testrepo child1 &&
 944        mk_child testrepo child2 &&
 945        (
 946                cd child1 &&
 947                git branch foo &&
 948                git symbolic-ref refs/heads/bar refs/heads/foo &&
 949                git config receive.denyCurrentBranch false
 950        ) &&
 951        (
 952                cd child2 &&
 953                >path2 &&
 954                git add path2 &&
 955                test_tick &&
 956                git commit -a -m child2 &&
 957                git branch foo &&
 958                >path3 &&
 959                git add path3 &&
 960                test_tick &&
 961                git commit -a -m child2 &&
 962                git branch bar &&
 963                test_must_fail git push ../child1 foo bar 2>stderr &&
 964                grep "refusing inconsistent update" stderr
 965        )
 966'
 967
 968test_force_push_tag () {
 969        tag_type_description=$1
 970        tag_args=$2
 971
 972        test_expect_success "force pushing required to update $tag_type_description" "
 973                mk_test testrepo heads/master &&
 974                mk_child testrepo child1 &&
 975                mk_child testrepo child2 &&
 976                (
 977                        cd child1 &&
 978                        git tag testTag &&
 979                        git push ../child2 testTag &&
 980                        >file1 &&
 981                        git add file1 &&
 982                        git commit -m 'file1' &&
 983                        git tag $tag_args testTag &&
 984                        test_must_fail git push ../child2 testTag &&
 985                        git push --force ../child2 testTag &&
 986                        git tag $tag_args testTag HEAD~ &&
 987                        test_must_fail git push ../child2 testTag &&
 988                        git push --force ../child2 testTag &&
 989
 990                        # Clobbering without + in refspec needs --force
 991                        git tag -f testTag &&
 992                        test_must_fail git push ../child2 'refs/tags/*:refs/tags/*' &&
 993                        git push --force ../child2 'refs/tags/*:refs/tags/*' &&
 994
 995                        # Clobbering with + in refspec does not need --force
 996                        git tag -f testTag HEAD~ &&
 997                        git push ../child2 '+refs/tags/*:refs/tags/*' &&
 998
 999                        # Clobbering with --no-force still obeys + in refspec
1000                        git tag -f testTag &&
1001                        git push --no-force ../child2 '+refs/tags/*:refs/tags/*' &&
1002
1003                        # Clobbering with/without --force and 'tag <name>' format
1004                        git tag -f testTag HEAD~ &&
1005                        test_must_fail git push ../child2 tag testTag &&
1006                        git push --force ../child2 tag testTag
1007                )
1008        "
1009}
1010
1011test_force_push_tag "lightweight tag" "-f"
1012test_force_push_tag "annotated tag" "-f -a -m'tag message'"
1013
1014test_force_fetch_tag () {
1015        tag_type_description=$1
1016        tag_args=$2
1017
1018        test_expect_success "fetch will not clobber an existing $tag_type_description without --force" "
1019                mk_test testrepo heads/master &&
1020                mk_child testrepo child1 &&
1021                mk_child testrepo child2 &&
1022                (
1023                        cd testrepo &&
1024                        git tag testTag &&
1025                        git -C ../child1 fetch origin tag testTag &&
1026                        >file1 &&
1027                        git add file1 &&
1028                        git commit -m 'file1' &&
1029                        git tag $tag_args testTag &&
1030                        test_must_fail git -C ../child1 fetch origin tag testTag &&
1031                        git -C ../child1 fetch origin '+refs/tags/*:refs/tags/*'
1032                )
1033        "
1034}
1035
1036test_force_fetch_tag "lightweight tag" "-f"
1037test_force_fetch_tag "annotated tag" "-f -a -m'tag message'"
1038
1039test_expect_success 'push --porcelain' '
1040        mk_empty testrepo &&
1041        echo >.git/foo  "To testrepo" &&
1042        echo >>.git/foo "*      refs/heads/master:refs/remotes/origin/master    [new branch]"  &&
1043        echo >>.git/foo "Done" &&
1044        git push >.git/bar --porcelain  testrepo refs/heads/master:refs/remotes/origin/master &&
1045        (
1046                cd testrepo &&
1047                echo "$the_commit commit        refs/remotes/origin/master" >expect &&
1048                git for-each-ref refs/remotes/origin >actual &&
1049                test_cmp expect actual
1050        ) &&
1051        test_cmp .git/foo .git/bar
1052'
1053
1054test_expect_success 'push --porcelain bad url' '
1055        mk_empty testrepo &&
1056        test_must_fail git push >.git/bar --porcelain asdfasdfasd refs/heads/master:refs/remotes/origin/master &&
1057        ! grep -q Done .git/bar
1058'
1059
1060test_expect_success 'push --porcelain rejected' '
1061        mk_empty testrepo &&
1062        git push testrepo refs/heads/master:refs/remotes/origin/master &&
1063        (cd testrepo &&
1064                git reset --hard origin/master^ &&
1065                git config receive.denyCurrentBranch true) &&
1066
1067        echo >.git/foo  "To testrepo"  &&
1068        echo >>.git/foo "!      refs/heads/master:refs/heads/master     [remote rejected] (branch is currently checked out)" &&
1069
1070        test_must_fail git push >.git/bar --porcelain  testrepo refs/heads/master:refs/heads/master &&
1071        test_cmp .git/foo .git/bar
1072'
1073
1074test_expect_success 'push --porcelain --dry-run rejected' '
1075        mk_empty testrepo &&
1076        git push testrepo refs/heads/master:refs/remotes/origin/master &&
1077        (cd testrepo &&
1078                git reset --hard origin/master &&
1079                git config receive.denyCurrentBranch true) &&
1080
1081        echo >.git/foo  "To testrepo"  &&
1082        echo >>.git/foo "!      refs/heads/master^:refs/heads/master    [rejected] (non-fast-forward)" &&
1083        echo >>.git/foo "Done" &&
1084
1085        test_must_fail git push >.git/bar --porcelain  --dry-run testrepo refs/heads/master^:refs/heads/master &&
1086        test_cmp .git/foo .git/bar
1087'
1088
1089test_expect_success 'push --prune' '
1090        mk_test testrepo heads/master heads/second heads/foo heads/bar &&
1091        git push --prune testrepo : &&
1092        check_push_result testrepo $the_commit heads/master &&
1093        check_push_result testrepo $the_first_commit heads/second &&
1094        ! check_push_result testrepo $the_first_commit heads/foo heads/bar
1095'
1096
1097test_expect_success 'push --prune refspec' '
1098        mk_test testrepo tmp/master tmp/second tmp/foo tmp/bar &&
1099        git push --prune testrepo "refs/heads/*:refs/tmp/*" &&
1100        check_push_result testrepo $the_commit tmp/master &&
1101        check_push_result testrepo $the_first_commit tmp/second &&
1102        ! check_push_result testrepo $the_first_commit tmp/foo tmp/bar
1103'
1104
1105for configsection in transfer receive
1106do
1107        test_expect_success "push to update a ref hidden by $configsection.hiderefs" '
1108                mk_test testrepo heads/master hidden/one hidden/two hidden/three &&
1109                (
1110                        cd testrepo &&
1111                        git config $configsection.hiderefs refs/hidden
1112                ) &&
1113
1114                # push to unhidden ref succeeds normally
1115                git push testrepo master:refs/heads/master &&
1116                check_push_result testrepo $the_commit heads/master &&
1117
1118                # push to update a hidden ref should fail
1119                test_must_fail git push testrepo master:refs/hidden/one &&
1120                check_push_result testrepo $the_first_commit hidden/one &&
1121
1122                # push to delete a hidden ref should fail
1123                test_must_fail git push testrepo :refs/hidden/two &&
1124                check_push_result testrepo $the_first_commit hidden/two &&
1125
1126                # idempotent push to update a hidden ref should fail
1127                test_must_fail git push testrepo $the_first_commit:refs/hidden/three &&
1128                check_push_result testrepo $the_first_commit hidden/three
1129        '
1130done
1131
1132test_expect_success 'fetch exact SHA1' '
1133        mk_test testrepo heads/master hidden/one &&
1134        git push testrepo master:refs/hidden/one &&
1135        (
1136                cd testrepo &&
1137                git config transfer.hiderefs refs/hidden
1138        ) &&
1139        check_push_result testrepo $the_commit hidden/one &&
1140
1141        mk_child testrepo child &&
1142        (
1143                cd child &&
1144
1145                # make sure $the_commit does not exist here
1146                git repack -a -d &&
1147                git prune &&
1148                test_must_fail git cat-file -t $the_commit &&
1149
1150                # Some protocol versions (e.g. 2) support fetching
1151                # unadvertised objects, so restrict this test to v0.
1152
1153                # fetching the hidden object should fail by default
1154                test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
1155                        git fetch -v ../testrepo $the_commit:refs/heads/copy 2>err &&
1156                test_i18ngrep "Server does not allow request for unadvertised object" err &&
1157                test_must_fail git rev-parse --verify refs/heads/copy &&
1158
1159                # the server side can allow it to succeed
1160                (
1161                        cd ../testrepo &&
1162                        git config uploadpack.allowtipsha1inwant true
1163                ) &&
1164
1165                git fetch -v ../testrepo $the_commit:refs/heads/copy master:refs/heads/extra &&
1166                cat >expect <<-EOF &&
1167                $the_commit
1168                $the_first_commit
1169                EOF
1170                {
1171                        git rev-parse --verify refs/heads/copy &&
1172                        git rev-parse --verify refs/heads/extra
1173                } >actual &&
1174                test_cmp expect actual
1175        )
1176'
1177
1178test_expect_success 'fetch exact SHA1 in protocol v2' '
1179        mk_test testrepo heads/master hidden/one &&
1180        git push testrepo master:refs/hidden/one &&
1181        git -C testrepo config transfer.hiderefs refs/hidden &&
1182        check_push_result testrepo $the_commit hidden/one &&
1183
1184        mk_child testrepo child &&
1185        git -C child config protocol.version 2 &&
1186
1187        # make sure $the_commit does not exist here
1188        git -C child repack -a -d &&
1189        git -C child prune &&
1190        test_must_fail git -C child cat-file -t $the_commit &&
1191
1192        # fetching the hidden object succeeds by default
1193        # NEEDSWORK: should this match the v0 behavior instead?
1194        git -C child fetch -v ../testrepo $the_commit:refs/heads/copy
1195'
1196
1197for configallowtipsha1inwant in true false
1198do
1199        test_expect_success "shallow fetch reachable SHA1 (but not a ref), allowtipsha1inwant=$configallowtipsha1inwant" '
1200                mk_empty testrepo &&
1201                (
1202                        cd testrepo &&
1203                        git config uploadpack.allowtipsha1inwant $configallowtipsha1inwant &&
1204                        git commit --allow-empty -m foo &&
1205                        git commit --allow-empty -m bar
1206                ) &&
1207                SHA1=$(git --git-dir=testrepo/.git rev-parse HEAD^) &&
1208                mk_empty shallow &&
1209                (
1210                        cd shallow &&
1211                        # Some protocol versions (e.g. 2) support fetching
1212                        # unadvertised objects, so restrict this test to v0.
1213                        test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
1214                                git fetch --depth=1 ../testrepo/.git $SHA1 &&
1215                        git --git-dir=../testrepo/.git config uploadpack.allowreachablesha1inwant true &&
1216                        git fetch --depth=1 ../testrepo/.git $SHA1 &&
1217                        git cat-file commit $SHA1
1218                )
1219        '
1220
1221        test_expect_success "deny fetch unreachable SHA1, allowtipsha1inwant=$configallowtipsha1inwant" '
1222                mk_empty testrepo &&
1223                (
1224                        cd testrepo &&
1225                        git config uploadpack.allowtipsha1inwant $configallowtipsha1inwant &&
1226                        git commit --allow-empty -m foo &&
1227                        git commit --allow-empty -m bar &&
1228                        git commit --allow-empty -m xyz
1229                ) &&
1230                SHA1_1=$(git --git-dir=testrepo/.git rev-parse HEAD^^) &&
1231                SHA1_2=$(git --git-dir=testrepo/.git rev-parse HEAD^) &&
1232                SHA1_3=$(git --git-dir=testrepo/.git rev-parse HEAD) &&
1233                (
1234                        cd testrepo &&
1235                        git reset --hard $SHA1_2 &&
1236                        git cat-file commit $SHA1_1 &&
1237                        git cat-file commit $SHA1_3
1238                ) &&
1239                mk_empty shallow &&
1240                (
1241                        cd shallow &&
1242                        # Some protocol versions (e.g. 2) support fetching
1243                        # unadvertised objects, so restrict this test to v0.
1244                        test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
1245                                git fetch ../testrepo/.git $SHA1_3 &&
1246                        test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
1247                                git fetch ../testrepo/.git $SHA1_1 &&
1248                        git --git-dir=../testrepo/.git config uploadpack.allowreachablesha1inwant true &&
1249                        git fetch ../testrepo/.git $SHA1_1 &&
1250                        git cat-file commit $SHA1_1 &&
1251                        test_must_fail git cat-file commit $SHA1_2 &&
1252                        git fetch ../testrepo/.git $SHA1_2 &&
1253                        git cat-file commit $SHA1_2 &&
1254                        test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
1255                                git fetch ../testrepo/.git $SHA1_3 2>err &&
1256                        test_i18ngrep "remote error:.*not our ref.*$SHA1_3\$" err
1257                )
1258        '
1259done
1260
1261test_expect_success 'fetch follows tags by default' '
1262        mk_test testrepo heads/master &&
1263        rm -fr src dst &&
1264        git init src &&
1265        (
1266                cd src &&
1267                git pull ../testrepo master &&
1268                git tag -m "annotated" tag &&
1269                git for-each-ref >tmp1 &&
1270                (
1271                        cat tmp1
1272                        sed -n "s|refs/heads/master$|refs/remotes/origin/master|p" tmp1
1273                ) |
1274                sort -k 3 >../expect
1275        ) &&
1276        git init dst &&
1277        (
1278                cd dst &&
1279                git remote add origin ../src &&
1280                git config branch.master.remote origin &&
1281                git config branch.master.merge refs/heads/master &&
1282                git pull &&
1283                git for-each-ref >../actual
1284        ) &&
1285        test_cmp expect actual
1286'
1287
1288test_expect_success 'peeled advertisements are not considered ref tips' '
1289        mk_empty testrepo &&
1290        git -C testrepo commit --allow-empty -m one &&
1291        git -C testrepo commit --allow-empty -m two &&
1292        git -C testrepo tag -m foo mytag HEAD^ &&
1293        oid=$(git -C testrepo rev-parse mytag^{commit}) &&
1294        test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
1295                git fetch testrepo $oid 2>err &&
1296        test_i18ngrep "Server does not allow request for unadvertised object" err
1297'
1298
1299test_expect_success 'pushing a specific ref applies remote.$name.push as refmap' '
1300        mk_test testrepo heads/master &&
1301        rm -fr src dst &&
1302        git init src &&
1303        git init --bare dst &&
1304        (
1305                cd src &&
1306                git pull ../testrepo master &&
1307                git branch next &&
1308                git config remote.dst.url ../dst &&
1309                git config remote.dst.push "+refs/heads/*:refs/remotes/src/*" &&
1310                git push dst master &&
1311                git show-ref refs/heads/master |
1312                sed -e "s|refs/heads/|refs/remotes/src/|" >../dst/expect
1313        ) &&
1314        (
1315                cd dst &&
1316                test_must_fail git show-ref refs/heads/next &&
1317                test_must_fail git show-ref refs/heads/master &&
1318                git show-ref refs/remotes/src/master >actual
1319        ) &&
1320        test_cmp dst/expect dst/actual
1321'
1322
1323test_expect_success 'with no remote.$name.push, it is not used as refmap' '
1324        mk_test testrepo heads/master &&
1325        rm -fr src dst &&
1326        git init src &&
1327        git init --bare dst &&
1328        (
1329                cd src &&
1330                git pull ../testrepo master &&
1331                git branch next &&
1332                git config remote.dst.url ../dst &&
1333                git config push.default matching &&
1334                git push dst master &&
1335                git show-ref refs/heads/master >../dst/expect
1336        ) &&
1337        (
1338                cd dst &&
1339                test_must_fail git show-ref refs/heads/next &&
1340                git show-ref refs/heads/master >actual
1341        ) &&
1342        test_cmp dst/expect dst/actual
1343'
1344
1345test_expect_success 'with no remote.$name.push, upstream mapping is used' '
1346        mk_test testrepo heads/master &&
1347        rm -fr src dst &&
1348        git init src &&
1349        git init --bare dst &&
1350        (
1351                cd src &&
1352                git pull ../testrepo master &&
1353                git branch next &&
1354                git config remote.dst.url ../dst &&
1355                git config remote.dst.fetch "+refs/heads/*:refs/remotes/dst/*" &&
1356                git config push.default upstream &&
1357
1358                git config branch.master.merge refs/heads/trunk &&
1359                git config branch.master.remote dst &&
1360
1361                git push dst master &&
1362                git show-ref refs/heads/master |
1363                sed -e "s|refs/heads/master|refs/heads/trunk|" >../dst/expect
1364        ) &&
1365        (
1366                cd dst &&
1367                test_must_fail git show-ref refs/heads/master &&
1368                test_must_fail git show-ref refs/heads/next &&
1369                git show-ref refs/heads/trunk >actual
1370        ) &&
1371        test_cmp dst/expect dst/actual
1372'
1373
1374test_expect_success 'push does not follow tags by default' '
1375        mk_test testrepo heads/master &&
1376        rm -fr src dst &&
1377        git init src &&
1378        git init --bare dst &&
1379        (
1380                cd src &&
1381                git pull ../testrepo master &&
1382                git tag -m "annotated" tag &&
1383                git checkout -b another &&
1384                git commit --allow-empty -m "future commit" &&
1385                git tag -m "future" future &&
1386                git checkout master &&
1387                git for-each-ref refs/heads/master >../expect &&
1388                git push ../dst master
1389        ) &&
1390        (
1391                cd dst &&
1392                git for-each-ref >../actual
1393        ) &&
1394        test_cmp expect actual
1395'
1396
1397test_expect_success 'push --follow-tags only pushes relevant tags' '
1398        mk_test testrepo heads/master &&
1399        rm -fr src dst &&
1400        git init src &&
1401        git init --bare dst &&
1402        (
1403                cd src &&
1404                git pull ../testrepo master &&
1405                git tag -m "annotated" tag &&
1406                git checkout -b another &&
1407                git commit --allow-empty -m "future commit" &&
1408                git tag -m "future" future &&
1409                git checkout master &&
1410                git for-each-ref refs/heads/master refs/tags/tag >../expect &&
1411                git push --follow-tags ../dst master
1412        ) &&
1413        (
1414                cd dst &&
1415                git for-each-ref >../actual
1416        ) &&
1417        test_cmp expect actual
1418'
1419
1420test_expect_success 'push --no-thin must produce non-thin pack' '
1421        cat >>path1 <<\EOF &&
1422keep base version of path1 big enough, compared to the new changes
1423later, in order to pass size heuristics in
1424builtin/pack-objects.c:try_delta()
1425EOF
1426        git commit -am initial &&
1427        git init no-thin &&
1428        git --git-dir=no-thin/.git config receive.unpacklimit 0 &&
1429        git push no-thin/.git refs/heads/master:refs/heads/foo &&
1430        echo modified >> path1 &&
1431        git commit -am modified &&
1432        git repack -adf &&
1433        rcvpck="git receive-pack --reject-thin-pack-for-testing" &&
1434        git push --no-thin --receive-pack="$rcvpck" no-thin/.git refs/heads/master:refs/heads/foo
1435'
1436
1437test_expect_success 'pushing a tag pushes the tagged object' '
1438        rm -rf dst.git &&
1439        blob=$(echo unreferenced | git hash-object -w --stdin) &&
1440        git tag -m foo tag-of-blob $blob &&
1441        git init --bare dst.git &&
1442        git push dst.git tag-of-blob &&
1443        # the receiving index-pack should have noticed
1444        # any problems, but we double check
1445        echo unreferenced >expect &&
1446        git --git-dir=dst.git cat-file blob tag-of-blob >actual &&
1447        test_cmp expect actual
1448'
1449
1450test_expect_success 'push into bare respects core.logallrefupdates' '
1451        rm -rf dst.git &&
1452        git init --bare dst.git &&
1453        git -C dst.git config core.logallrefupdates true &&
1454
1455        # double push to test both with and without
1456        # the actual pack transfer
1457        git push dst.git master:one &&
1458        echo "one@{0} push" >expect &&
1459        git -C dst.git log -g --format="%gd %gs" one >actual &&
1460        test_cmp expect actual &&
1461
1462        git push dst.git master:two &&
1463        echo "two@{0} push" >expect &&
1464        git -C dst.git log -g --format="%gd %gs" two >actual &&
1465        test_cmp expect actual
1466'
1467
1468test_expect_success 'fetch into bare respects core.logallrefupdates' '
1469        rm -rf dst.git &&
1470        git init --bare dst.git &&
1471        (
1472                cd dst.git &&
1473                git config core.logallrefupdates true &&
1474
1475                # as above, we double-fetch to test both
1476                # with and without pack transfer
1477                git fetch .. master:one &&
1478                echo "one@{0} fetch .. master:one: storing head" >expect &&
1479                git log -g --format="%gd %gs" one >actual &&
1480                test_cmp expect actual &&
1481
1482                git fetch .. master:two &&
1483                echo "two@{0} fetch .. master:two: storing head" >expect &&
1484                git log -g --format="%gd %gs" two >actual &&
1485                test_cmp expect actual
1486        )
1487'
1488
1489test_expect_success 'receive.denyCurrentBranch = updateInstead' '
1490        git push testrepo master &&
1491        (
1492                cd testrepo &&
1493                git reset --hard &&
1494                git config receive.denyCurrentBranch updateInstead
1495        ) &&
1496        test_commit third path2 &&
1497
1498        # Try pushing into a repository with pristine working tree
1499        git push testrepo master &&
1500        (
1501                cd testrepo &&
1502                git update-index -q --refresh &&
1503                git diff-files --quiet -- &&
1504                git diff-index --quiet --cached HEAD -- &&
1505                test third = "$(cat path2)" &&
1506                test $(git -C .. rev-parse HEAD) = $(git rev-parse HEAD)
1507        ) &&
1508
1509        # Try pushing into a repository with working tree needing a refresh
1510        (
1511                cd testrepo &&
1512                git reset --hard HEAD^ &&
1513                test $(git -C .. rev-parse HEAD^) = $(git rev-parse HEAD) &&
1514                test-tool chmtime +100 path1
1515        ) &&
1516        git push testrepo master &&
1517        (
1518                cd testrepo &&
1519                git update-index -q --refresh &&
1520                git diff-files --quiet -- &&
1521                git diff-index --quiet --cached HEAD -- &&
1522                test_cmp ../path1 path1 &&
1523                test third = "$(cat path2)" &&
1524                test $(git -C .. rev-parse HEAD) = $(git rev-parse HEAD)
1525        ) &&
1526
1527        # Update what is to be pushed
1528        test_commit fourth path2 &&
1529
1530        # Try pushing into a repository with a dirty working tree
1531        # (1) the working tree updated
1532        (
1533                cd testrepo &&
1534                echo changed >path1
1535        ) &&
1536        test_must_fail git push testrepo master &&
1537        (
1538                cd testrepo &&
1539                test $(git -C .. rev-parse HEAD^) = $(git rev-parse HEAD) &&
1540                git diff --quiet --cached &&
1541                test changed = "$(cat path1)"
1542        ) &&
1543
1544        # (2) the index updated
1545        (
1546                cd testrepo &&
1547                echo changed >path1 &&
1548                git add path1
1549        ) &&
1550        test_must_fail git push testrepo master &&
1551        (
1552                cd testrepo &&
1553                test $(git -C .. rev-parse HEAD^) = $(git rev-parse HEAD) &&
1554                git diff --quiet &&
1555                test changed = "$(cat path1)"
1556        ) &&
1557
1558        # Introduce a new file in the update
1559        test_commit fifth path3 &&
1560
1561        # (3) the working tree has an untracked file that would interfere
1562        (
1563                cd testrepo &&
1564                git reset --hard &&
1565                echo changed >path3
1566        ) &&
1567        test_must_fail git push testrepo master &&
1568        (
1569                cd testrepo &&
1570                test $(git -C .. rev-parse HEAD^^) = $(git rev-parse HEAD) &&
1571                git diff --quiet &&
1572                git diff --quiet --cached &&
1573                test changed = "$(cat path3)"
1574        ) &&
1575
1576        # (4) the target changes to what gets pushed but it still is a change
1577        (
1578                cd testrepo &&
1579                git reset --hard &&
1580                echo fifth >path3 &&
1581                git add path3
1582        ) &&
1583        test_must_fail git push testrepo master &&
1584        (
1585                cd testrepo &&
1586                test $(git -C .. rev-parse HEAD^^) = $(git rev-parse HEAD) &&
1587                git diff --quiet &&
1588                test fifth = "$(cat path3)"
1589        ) &&
1590
1591        # (5) push into void
1592        rm -fr void &&
1593        git init void &&
1594        (
1595                cd void &&
1596                git config receive.denyCurrentBranch updateInstead
1597        ) &&
1598        git push void master &&
1599        (
1600                cd void &&
1601                test $(git -C .. rev-parse master) = $(git rev-parse HEAD) &&
1602                git diff --quiet &&
1603                git diff --cached --quiet
1604        ) &&
1605
1606        # (6) updateInstead intervened by fast-forward check
1607        test_must_fail git push void master^:master &&
1608        test $(git -C void rev-parse HEAD) = $(git rev-parse master) &&
1609        git -C void diff --quiet &&
1610        git -C void diff --cached --quiet
1611'
1612
1613test_expect_success 'updateInstead with push-to-checkout hook' '
1614        rm -fr testrepo &&
1615        git init testrepo &&
1616        (
1617                cd testrepo &&
1618                git pull .. master &&
1619                git reset --hard HEAD^^ &&
1620                git tag initial &&
1621                git config receive.denyCurrentBranch updateInstead &&
1622                write_script .git/hooks/push-to-checkout <<-\EOF
1623                echo >&2 updating from $(git rev-parse HEAD)
1624                echo >&2 updating to "$1"
1625
1626                git update-index -q --refresh &&
1627                git read-tree -u -m HEAD "$1" || {
1628                        status=$?
1629                        echo >&2 read-tree failed
1630                        exit $status
1631                }
1632                EOF
1633        ) &&
1634
1635        # Try pushing into a pristine
1636        git push testrepo master &&
1637        (
1638                cd testrepo &&
1639                git diff --quiet &&
1640                git diff HEAD --quiet &&
1641                test $(git -C .. rev-parse HEAD) = $(git rev-parse HEAD)
1642        ) &&
1643
1644        # Try pushing into a repository with conflicting change
1645        (
1646                cd testrepo &&
1647                git reset --hard initial &&
1648                echo conflicting >path2
1649        ) &&
1650        test_must_fail git push testrepo master &&
1651        (
1652                cd testrepo &&
1653                test $(git rev-parse initial) = $(git rev-parse HEAD) &&
1654                test conflicting = "$(cat path2)" &&
1655                git diff-index --quiet --cached HEAD
1656        ) &&
1657
1658        # Try pushing into a repository with unrelated change
1659        (
1660                cd testrepo &&
1661                git reset --hard initial &&
1662                echo unrelated >path1 &&
1663                echo irrelevant >path5 &&
1664                git add path5
1665        ) &&
1666        git push testrepo master &&
1667        (
1668                cd testrepo &&
1669                test "$(cat path1)" = unrelated &&
1670                test "$(cat path5)" = irrelevant &&
1671                test "$(git diff --name-only --cached HEAD)" = path5 &&
1672                test $(git -C .. rev-parse HEAD) = $(git rev-parse HEAD)
1673        ) &&
1674
1675        # push into void
1676        rm -fr void &&
1677        git init void &&
1678        (
1679                cd void &&
1680                git config receive.denyCurrentBranch updateInstead &&
1681                write_script .git/hooks/push-to-checkout <<-\EOF
1682                if git rev-parse --quiet --verify HEAD
1683                then
1684                        has_head=yes
1685                        echo >&2 updating from $(git rev-parse HEAD)
1686                else
1687                        has_head=no
1688                        echo >&2 pushing into void
1689                fi
1690                echo >&2 updating to "$1"
1691
1692                git update-index -q --refresh &&
1693                case "$has_head" in
1694                yes)
1695                        git read-tree -u -m HEAD "$1" ;;
1696                no)
1697                        git read-tree -u -m "$1" ;;
1698                esac || {
1699                        status=$?
1700                        echo >&2 read-tree failed
1701                        exit $status
1702                }
1703                EOF
1704        ) &&
1705
1706        git push void master &&
1707        (
1708                cd void &&
1709                git diff --quiet &&
1710                git diff --cached --quiet &&
1711                test $(git -C .. rev-parse HEAD) = $(git rev-parse HEAD)
1712        )
1713'
1714
1715test_done