f394271d8ca11d01c9d94186817948c3ad32bdde
   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'
  15
  16. ./test-lib.sh
  17
  18D=`pwd`
  19
  20mk_empty () {
  21        rm -fr testrepo &&
  22        mkdir testrepo &&
  23        (
  24                cd testrepo &&
  25                git init &&
  26                git config receive.denyCurrentBranch warn &&
  27                mv .git/hooks .git/hooks-disabled
  28        )
  29}
  30
  31mk_test () {
  32        mk_empty &&
  33        (
  34                for ref in "$@"
  35                do
  36                        git push testrepo $the_first_commit:refs/$ref ||
  37                        exit
  38                done &&
  39                cd testrepo &&
  40                for ref in "$@"
  41                do
  42                        echo "$the_first_commit" >expect &&
  43                        git show-ref -s --verify refs/$ref >actual &&
  44                        test_cmp expect actual ||
  45                        exit
  46                done &&
  47                git fsck --full
  48        )
  49}
  50
  51mk_test_with_hooks() {
  52        mk_test "$@" &&
  53        (
  54                cd testrepo &&
  55                mkdir .git/hooks &&
  56                cd .git/hooks &&
  57
  58                cat >pre-receive <<-'EOF' &&
  59                #!/bin/sh
  60                cat - >>pre-receive.actual
  61                EOF
  62
  63                cat >update <<-'EOF' &&
  64                #!/bin/sh
  65                printf "%s %s %s\n" "$@" >>update.actual
  66                EOF
  67
  68                cat >post-receive <<-'EOF' &&
  69                #!/bin/sh
  70                cat - >>post-receive.actual
  71                EOF
  72
  73                cat >post-update <<-'EOF' &&
  74                #!/bin/sh
  75                for ref in "$@"
  76                do
  77                        printf "%s\n" "$ref" >>post-update.actual
  78                done
  79                EOF
  80
  81                chmod +x pre-receive update post-receive post-update
  82        )
  83}
  84
  85mk_child() {
  86        rm -rf "$1" &&
  87        git clone testrepo "$1"
  88}
  89
  90check_push_result () {
  91        (
  92                cd testrepo &&
  93                echo "$1" >expect &&
  94                shift &&
  95                for ref in "$@"
  96                do
  97                        git show-ref -s --verify refs/$ref >actual &&
  98                        test_cmp expect actual ||
  99                        exit
 100                done &&
 101                git fsck --full
 102        )
 103}
 104
 105test_expect_success setup '
 106
 107        >path1 &&
 108        git add path1 &&
 109        test_tick &&
 110        git commit -a -m repo &&
 111        the_first_commit=$(git show-ref -s --verify refs/heads/master) &&
 112
 113        >path2 &&
 114        git add path2 &&
 115        test_tick &&
 116        git commit -a -m second &&
 117        the_commit=$(git show-ref -s --verify refs/heads/master)
 118
 119'
 120
 121test_expect_success 'fetch without wildcard' '
 122        mk_empty &&
 123        (
 124                cd testrepo &&
 125                git fetch .. refs/heads/master:refs/remotes/origin/master &&
 126
 127                echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 128                git for-each-ref refs/remotes/origin >actual &&
 129                test_cmp expect actual
 130        )
 131'
 132
 133test_expect_success 'fetch with wildcard' '
 134        mk_empty &&
 135        (
 136                cd testrepo &&
 137                git config remote.up.url .. &&
 138                git config remote.up.fetch "refs/heads/*:refs/remotes/origin/*" &&
 139                git fetch up &&
 140
 141                echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 142                git for-each-ref refs/remotes/origin >actual &&
 143                test_cmp expect actual
 144        )
 145'
 146
 147test_expect_success 'fetch with insteadOf' '
 148        mk_empty &&
 149        (
 150                TRASH=$(pwd)/ &&
 151                cd testrepo &&
 152                git config "url.$TRASH.insteadOf" trash/ &&
 153                git config remote.up.url trash/. &&
 154                git config remote.up.fetch "refs/heads/*:refs/remotes/origin/*" &&
 155                git fetch up &&
 156
 157                echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 158                git for-each-ref refs/remotes/origin >actual &&
 159                test_cmp expect actual
 160        )
 161'
 162
 163test_expect_success 'fetch with pushInsteadOf (should not rewrite)' '
 164        mk_empty &&
 165        (
 166                TRASH=$(pwd)/ &&
 167                cd testrepo &&
 168                git config "url.trash/.pushInsteadOf" "$TRASH" &&
 169                git config remote.up.url "$TRASH." &&
 170                git config remote.up.fetch "refs/heads/*:refs/remotes/origin/*" &&
 171                git fetch up &&
 172
 173                echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 174                git for-each-ref refs/remotes/origin >actual &&
 175                test_cmp expect actual
 176        )
 177'
 178
 179test_expect_success 'push without wildcard' '
 180        mk_empty &&
 181
 182        git push testrepo refs/heads/master:refs/remotes/origin/master &&
 183        (
 184                cd testrepo &&
 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 with wildcard' '
 192        mk_empty &&
 193
 194        git push testrepo "refs/heads/*:refs/remotes/origin/*" &&
 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 insteadOf' '
 204        mk_empty &&
 205        TRASH="$(pwd)/" &&
 206        test_config "url.$TRASH.insteadOf" trash/ &&
 207        git push trash/testrepo refs/heads/master:refs/remotes/origin/master &&
 208        (
 209                cd testrepo &&
 210                echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 211                git for-each-ref refs/remotes/origin >actual &&
 212                test_cmp expect actual
 213        )
 214'
 215
 216test_expect_success 'push with pushInsteadOf' '
 217        mk_empty &&
 218        TRASH="$(pwd)/" &&
 219        test_config "url.$TRASH.pushInsteadOf" trash/ &&
 220        git push trash/testrepo refs/heads/master:refs/remotes/origin/master &&
 221        (
 222                cd testrepo &&
 223                echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 224                git for-each-ref refs/remotes/origin >actual &&
 225                test_cmp expect actual
 226        )
 227'
 228
 229test_expect_success 'push with pushInsteadOf and explicit pushurl (pushInsteadOf should not rewrite)' '
 230        mk_empty &&
 231        TRASH="$(pwd)/" &&
 232        test_config "url.trash2/.pushInsteadOf" trash/ &&
 233        test_config remote.r.url trash/wrong &&
 234        test_config remote.r.pushurl "$TRASH/testrepo" &&
 235        git push r refs/heads/master:refs/remotes/origin/master &&
 236        (
 237                cd testrepo &&
 238                echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 239                git for-each-ref refs/remotes/origin >actual &&
 240                test_cmp expect actual
 241        )
 242'
 243
 244test_expect_success 'push with matching heads' '
 245
 246        mk_test heads/master &&
 247        git push testrepo &&
 248        check_push_result $the_commit heads/master
 249
 250'
 251
 252test_expect_success 'push with matching heads on the command line' '
 253
 254        mk_test heads/master &&
 255        git push testrepo : &&
 256        check_push_result $the_commit heads/master
 257
 258'
 259
 260test_expect_success 'failed (non-fast-forward) push with matching heads' '
 261
 262        mk_test heads/master &&
 263        git push testrepo : &&
 264        git commit --amend -massaged &&
 265        test_must_fail git push testrepo &&
 266        check_push_result $the_commit heads/master &&
 267        git reset --hard $the_commit
 268
 269'
 270
 271test_expect_success 'push --force with matching heads' '
 272
 273        mk_test heads/master &&
 274        git push testrepo : &&
 275        git commit --amend -massaged &&
 276        git push --force testrepo &&
 277        ! check_push_result $the_commit heads/master &&
 278        git reset --hard $the_commit
 279
 280'
 281
 282test_expect_success 'push with matching heads and forced update' '
 283
 284        mk_test heads/master &&
 285        git push testrepo : &&
 286        git commit --amend -massaged &&
 287        git push testrepo +: &&
 288        ! check_push_result $the_commit heads/master &&
 289        git reset --hard $the_commit
 290
 291'
 292
 293test_expect_success 'push with no ambiguity (1)' '
 294
 295        mk_test heads/master &&
 296        git push testrepo master:master &&
 297        check_push_result $the_commit heads/master
 298
 299'
 300
 301test_expect_success 'push with no ambiguity (2)' '
 302
 303        mk_test remotes/origin/master &&
 304        git push testrepo master:origin/master &&
 305        check_push_result $the_commit remotes/origin/master
 306
 307'
 308
 309test_expect_success 'push with colon-less refspec, no ambiguity' '
 310
 311        mk_test heads/master heads/t/master &&
 312        git branch -f t/master master &&
 313        git push testrepo master &&
 314        check_push_result $the_commit heads/master &&
 315        check_push_result $the_first_commit heads/t/master
 316
 317'
 318
 319test_expect_success 'push with weak ambiguity (1)' '
 320
 321        mk_test heads/master remotes/origin/master &&
 322        git push testrepo master:master &&
 323        check_push_result $the_commit heads/master &&
 324        check_push_result $the_first_commit remotes/origin/master
 325
 326'
 327
 328test_expect_success 'push with weak ambiguity (2)' '
 329
 330        mk_test heads/master remotes/origin/master remotes/another/master &&
 331        git push testrepo master:master &&
 332        check_push_result $the_commit heads/master &&
 333        check_push_result $the_first_commit remotes/origin/master remotes/another/master
 334
 335'
 336
 337test_expect_success 'push with ambiguity' '
 338
 339        mk_test heads/frotz tags/frotz &&
 340        test_must_fail git push testrepo master:frotz &&
 341        check_push_result $the_first_commit heads/frotz tags/frotz
 342
 343'
 344
 345test_expect_success 'push with colon-less refspec (1)' '
 346
 347        mk_test heads/frotz tags/frotz &&
 348        git branch -f frotz master &&
 349        git push testrepo frotz &&
 350        check_push_result $the_commit heads/frotz &&
 351        check_push_result $the_first_commit tags/frotz
 352
 353'
 354
 355test_expect_success 'push with colon-less refspec (2)' '
 356
 357        mk_test heads/frotz tags/frotz &&
 358        if git show-ref --verify -q refs/heads/frotz
 359        then
 360                git branch -D frotz
 361        fi &&
 362        git tag -f frotz &&
 363        git push -f testrepo frotz &&
 364        check_push_result $the_commit tags/frotz &&
 365        check_push_result $the_first_commit heads/frotz
 366
 367'
 368
 369test_expect_success 'push with colon-less refspec (3)' '
 370
 371        mk_test &&
 372        if git show-ref --verify -q refs/tags/frotz
 373        then
 374                git tag -d frotz
 375        fi &&
 376        git branch -f frotz master &&
 377        git push testrepo frotz &&
 378        check_push_result $the_commit heads/frotz &&
 379        test 1 = $( cd testrepo && git show-ref | wc -l )
 380'
 381
 382test_expect_success 'push with colon-less refspec (4)' '
 383
 384        mk_test &&
 385        if git show-ref --verify -q refs/heads/frotz
 386        then
 387                git branch -D frotz
 388        fi &&
 389        git tag -f frotz &&
 390        git push testrepo frotz &&
 391        check_push_result $the_commit tags/frotz &&
 392        test 1 = $( cd testrepo && git show-ref | wc -l )
 393
 394'
 395
 396test_expect_success 'push head with non-existent, incomplete dest' '
 397
 398        mk_test &&
 399        git push testrepo master:branch &&
 400        check_push_result $the_commit heads/branch
 401
 402'
 403
 404test_expect_success 'push tag with non-existent, incomplete dest' '
 405
 406        mk_test &&
 407        git tag -f v1.0 &&
 408        git push testrepo v1.0:tag &&
 409        check_push_result $the_commit tags/tag
 410
 411'
 412
 413test_expect_success 'push sha1 with non-existent, incomplete dest' '
 414
 415        mk_test &&
 416        test_must_fail git push testrepo `git rev-parse master`:foo
 417
 418'
 419
 420test_expect_success 'push ref expression with non-existent, incomplete dest' '
 421
 422        mk_test &&
 423        test_must_fail git push testrepo master^:branch
 424
 425'
 426
 427test_expect_success 'push with HEAD' '
 428
 429        mk_test heads/master &&
 430        git checkout master &&
 431        git push testrepo HEAD &&
 432        check_push_result $the_commit heads/master
 433
 434'
 435
 436test_expect_success 'push with HEAD nonexisting at remote' '
 437
 438        mk_test heads/master &&
 439        git checkout -b local master &&
 440        git push testrepo HEAD &&
 441        check_push_result $the_commit heads/local
 442'
 443
 444test_expect_success 'push with +HEAD' '
 445
 446        mk_test heads/master &&
 447        git checkout master &&
 448        git branch -D local &&
 449        git checkout -b local &&
 450        git push testrepo master local &&
 451        check_push_result $the_commit heads/master &&
 452        check_push_result $the_commit heads/local &&
 453
 454        # Without force rewinding should fail
 455        git reset --hard HEAD^ &&
 456        test_must_fail git push testrepo HEAD &&
 457        check_push_result $the_commit heads/local &&
 458
 459        # With force rewinding should succeed
 460        git push testrepo +HEAD &&
 461        check_push_result $the_first_commit heads/local
 462
 463'
 464
 465test_expect_success 'push HEAD with non-existent, incomplete dest' '
 466
 467        mk_test &&
 468        git checkout master &&
 469        git push testrepo HEAD:branch &&
 470        check_push_result $the_commit heads/branch
 471
 472'
 473
 474test_expect_success 'push with config remote.*.push = HEAD' '
 475
 476        mk_test heads/local &&
 477        git checkout master &&
 478        git branch -f local $the_commit &&
 479        (
 480                cd testrepo &&
 481                git checkout local &&
 482                git reset --hard $the_first_commit
 483        ) &&
 484        test_config remote.there.url testrepo &&
 485        test_config remote.there.push HEAD &&
 486        test_config branch.master.remote there &&
 487        git push &&
 488        check_push_result $the_commit heads/master &&
 489        check_push_result $the_first_commit heads/local
 490'
 491
 492test_expect_success 'push with config remote.*.pushurl' '
 493
 494        mk_test heads/master &&
 495        git checkout master &&
 496        test_config remote.there.url test2repo &&
 497        test_config remote.there.pushurl testrepo &&
 498        git push there &&
 499        check_push_result $the_commit heads/master
 500'
 501
 502test_expect_success 'push with dry-run' '
 503
 504        mk_test heads/master &&
 505        (
 506                cd testrepo &&
 507                old_commit=$(git show-ref -s --verify refs/heads/master)
 508        ) &&
 509        git push --dry-run testrepo &&
 510        check_push_result $old_commit heads/master
 511'
 512
 513test_expect_success 'push updates local refs' '
 514
 515        mk_test heads/master &&
 516        mk_child child &&
 517        (
 518                cd child &&
 519                git pull .. master &&
 520                git push &&
 521                test $(git rev-parse master) = \
 522                        $(git rev-parse remotes/origin/master)
 523        )
 524
 525'
 526
 527test_expect_success 'push updates up-to-date local refs' '
 528
 529        mk_test heads/master &&
 530        mk_child child1 &&
 531        mk_child child2 &&
 532        (cd child1 && git pull .. master && git push) &&
 533        (
 534                cd child2 &&
 535                git pull ../child1 master &&
 536                git push &&
 537                test $(git rev-parse master) = \
 538                        $(git rev-parse remotes/origin/master)
 539        )
 540
 541'
 542
 543test_expect_success 'push preserves up-to-date packed refs' '
 544
 545        mk_test heads/master &&
 546        mk_child child &&
 547        (
 548                cd child &&
 549                git push &&
 550                ! test -f .git/refs/remotes/origin/master
 551        )
 552
 553'
 554
 555test_expect_success 'push does not update local refs on failure' '
 556
 557        mk_test heads/master &&
 558        mk_child child &&
 559        mkdir testrepo/.git/hooks &&
 560        echo "#!/no/frobnication/today" >testrepo/.git/hooks/pre-receive &&
 561        chmod +x testrepo/.git/hooks/pre-receive &&
 562        (
 563                cd child &&
 564                git pull .. master
 565                test_must_fail git push &&
 566                test $(git rev-parse master) != \
 567                        $(git rev-parse remotes/origin/master)
 568        )
 569
 570'
 571
 572test_expect_success 'allow deleting an invalid remote ref' '
 573
 574        mk_test heads/master &&
 575        rm -f testrepo/.git/objects/??/* &&
 576        git push testrepo :refs/heads/master &&
 577        (cd testrepo && test_must_fail git rev-parse --verify refs/heads/master)
 578
 579'
 580
 581test_expect_success 'pushing valid refs triggers post-receive and post-update hooks' '
 582        mk_test_with_hooks heads/master heads/next &&
 583        orgmaster=$(cd testrepo && git show-ref -s --verify refs/heads/master) &&
 584        newmaster=$(git show-ref -s --verify refs/heads/master) &&
 585        orgnext=$(cd testrepo && git show-ref -s --verify refs/heads/next) &&
 586        newnext=$_z40 &&
 587        git push testrepo refs/heads/master:refs/heads/master :refs/heads/next &&
 588        (
 589                cd testrepo/.git &&
 590                cat >pre-receive.expect <<-EOF &&
 591                $orgmaster $newmaster refs/heads/master
 592                $orgnext $newnext refs/heads/next
 593                EOF
 594
 595                cat >update.expect <<-EOF &&
 596                refs/heads/master $orgmaster $newmaster
 597                refs/heads/next $orgnext $newnext
 598                EOF
 599
 600                cat >post-receive.expect <<-EOF &&
 601                $orgmaster $newmaster refs/heads/master
 602                $orgnext $newnext refs/heads/next
 603                EOF
 604
 605                cat >post-update.expect <<-EOF &&
 606                refs/heads/master
 607                refs/heads/next
 608                EOF
 609
 610                test_cmp pre-receive.expect pre-receive.actual &&
 611                test_cmp update.expect update.actual &&
 612                test_cmp post-receive.expect post-receive.actual &&
 613                test_cmp post-update.expect post-update.actual
 614        )
 615'
 616
 617test_expect_success 'deleting dangling ref triggers hooks with correct args' '
 618        mk_test_with_hooks heads/master &&
 619        rm -f testrepo/.git/objects/??/* &&
 620        git push testrepo :refs/heads/master &&
 621        (
 622                cd testrepo/.git &&
 623                cat >pre-receive.expect <<-EOF &&
 624                $_z40 $_z40 refs/heads/master
 625                EOF
 626
 627                cat >update.expect <<-EOF &&
 628                refs/heads/master $_z40 $_z40
 629                EOF
 630
 631                cat >post-receive.expect <<-EOF &&
 632                $_z40 $_z40 refs/heads/master
 633                EOF
 634
 635                cat >post-update.expect <<-EOF &&
 636                refs/heads/master
 637                EOF
 638
 639                test_cmp pre-receive.expect pre-receive.actual &&
 640                test_cmp update.expect update.actual &&
 641                test_cmp post-receive.expect post-receive.actual &&
 642                test_cmp post-update.expect post-update.actual
 643        )
 644'
 645
 646test_expect_success 'deletion of a non-existent ref is not fed to post-receive and post-update hooks' '
 647        mk_test_with_hooks heads/master &&
 648        orgmaster=$(cd testrepo && git show-ref -s --verify refs/heads/master) &&
 649        newmaster=$(git show-ref -s --verify refs/heads/master) &&
 650        git push testrepo master :refs/heads/nonexistent &&
 651        (
 652                cd testrepo/.git &&
 653                cat >pre-receive.expect <<-EOF &&
 654                $orgmaster $newmaster refs/heads/master
 655                $_z40 $_z40 refs/heads/nonexistent
 656                EOF
 657
 658                cat >update.expect <<-EOF &&
 659                refs/heads/master $orgmaster $newmaster
 660                refs/heads/nonexistent $_z40 $_z40
 661                EOF
 662
 663                cat >post-receive.expect <<-EOF &&
 664                $orgmaster $newmaster refs/heads/master
 665                EOF
 666
 667                cat >post-update.expect <<-EOF &&
 668                refs/heads/master
 669                EOF
 670
 671                test_cmp pre-receive.expect pre-receive.actual &&
 672                test_cmp update.expect update.actual &&
 673                test_cmp post-receive.expect post-receive.actual &&
 674                test_cmp post-update.expect post-update.actual
 675        )
 676'
 677
 678test_expect_success 'deletion of a non-existent ref alone does trigger post-receive and post-update hooks' '
 679        mk_test_with_hooks heads/master &&
 680        git push testrepo :refs/heads/nonexistent &&
 681        (
 682                cd testrepo/.git &&
 683                cat >pre-receive.expect <<-EOF &&
 684                $_z40 $_z40 refs/heads/nonexistent
 685                EOF
 686
 687                cat >update.expect <<-EOF &&
 688                refs/heads/nonexistent $_z40 $_z40
 689                EOF
 690
 691                test_cmp pre-receive.expect pre-receive.actual &&
 692                test_cmp update.expect update.actual &&
 693                test_path_is_missing post-receive.actual &&
 694                test_path_is_missing post-update.actual
 695        )
 696'
 697
 698test_expect_success 'mixed ref updates, deletes, invalid deletes trigger hooks with correct input' '
 699        mk_test_with_hooks heads/master heads/next heads/pu &&
 700        orgmaster=$(cd testrepo && git show-ref -s --verify refs/heads/master) &&
 701        newmaster=$(git show-ref -s --verify refs/heads/master) &&
 702        orgnext=$(cd testrepo && git show-ref -s --verify refs/heads/next) &&
 703        newnext=$_z40 &&
 704        orgpu=$(cd testrepo && git show-ref -s --verify refs/heads/pu) &&
 705        newpu=$(git show-ref -s --verify refs/heads/master) &&
 706        git push testrepo refs/heads/master:refs/heads/master \
 707            refs/heads/master:refs/heads/pu :refs/heads/next \
 708            :refs/heads/nonexistent &&
 709        (
 710                cd testrepo/.git &&
 711                cat >pre-receive.expect <<-EOF &&
 712                $orgmaster $newmaster refs/heads/master
 713                $orgnext $newnext refs/heads/next
 714                $orgpu $newpu refs/heads/pu
 715                $_z40 $_z40 refs/heads/nonexistent
 716                EOF
 717
 718                cat >update.expect <<-EOF &&
 719                refs/heads/master $orgmaster $newmaster
 720                refs/heads/next $orgnext $newnext
 721                refs/heads/pu $orgpu $newpu
 722                refs/heads/nonexistent $_z40 $_z40
 723                EOF
 724
 725                cat >post-receive.expect <<-EOF &&
 726                $orgmaster $newmaster refs/heads/master
 727                $orgnext $newnext refs/heads/next
 728                $orgpu $newpu refs/heads/pu
 729                EOF
 730
 731                cat >post-update.expect <<-EOF &&
 732                refs/heads/master
 733                refs/heads/next
 734                refs/heads/pu
 735                EOF
 736
 737                test_cmp pre-receive.expect pre-receive.actual &&
 738                test_cmp update.expect update.actual &&
 739                test_cmp post-receive.expect post-receive.actual &&
 740                test_cmp post-update.expect post-update.actual
 741        )
 742'
 743
 744test_expect_success 'allow deleting a ref using --delete' '
 745        mk_test heads/master &&
 746        (cd testrepo && git config receive.denyDeleteCurrent warn) &&
 747        git push testrepo --delete master &&
 748        (cd testrepo && test_must_fail git rev-parse --verify refs/heads/master)
 749'
 750
 751test_expect_success 'allow deleting a tag using --delete' '
 752        mk_test heads/master &&
 753        git tag -a -m dummy_message deltag heads/master &&
 754        git push testrepo --tags &&
 755        (cd testrepo && git rev-parse --verify -q refs/tags/deltag) &&
 756        git push testrepo --delete tag deltag &&
 757        (cd testrepo && test_must_fail git rev-parse --verify refs/tags/deltag)
 758'
 759
 760test_expect_success 'push --delete without args aborts' '
 761        mk_test heads/master &&
 762        test_must_fail git push testrepo --delete
 763'
 764
 765test_expect_success 'push --delete refuses src:dest refspecs' '
 766        mk_test heads/master &&
 767        test_must_fail git push testrepo --delete master:foo
 768'
 769
 770test_expect_success 'warn on push to HEAD of non-bare repository' '
 771        mk_test heads/master &&
 772        (
 773                cd testrepo &&
 774                git checkout master &&
 775                git config receive.denyCurrentBranch warn
 776        ) &&
 777        git push testrepo master 2>stderr &&
 778        grep "warning: updating the current branch" stderr
 779'
 780
 781test_expect_success 'deny push to HEAD of non-bare repository' '
 782        mk_test heads/master &&
 783        (
 784                cd testrepo &&
 785                git checkout master &&
 786                git config receive.denyCurrentBranch true
 787        ) &&
 788        test_must_fail git push testrepo master
 789'
 790
 791test_expect_success 'allow push to HEAD of bare repository (bare)' '
 792        mk_test heads/master &&
 793        (
 794                cd testrepo &&
 795                git checkout master &&
 796                git config receive.denyCurrentBranch true &&
 797                git config core.bare true
 798        ) &&
 799        git push testrepo master 2>stderr &&
 800        ! grep "warning: updating the current branch" stderr
 801'
 802
 803test_expect_success 'allow push to HEAD of non-bare repository (config)' '
 804        mk_test heads/master &&
 805        (
 806                cd testrepo &&
 807                git checkout master &&
 808                git config receive.denyCurrentBranch false
 809        ) &&
 810        git push testrepo master 2>stderr &&
 811        ! grep "warning: updating the current branch" stderr
 812'
 813
 814test_expect_success 'fetch with branches' '
 815        mk_empty &&
 816        git branch second $the_first_commit &&
 817        git checkout second &&
 818        echo ".." > testrepo/.git/branches/branch1 &&
 819        (
 820                cd testrepo &&
 821                git fetch branch1 &&
 822                echo "$the_commit commit        refs/heads/branch1" >expect &&
 823                git for-each-ref refs/heads >actual &&
 824                test_cmp expect actual
 825        ) &&
 826        git checkout master
 827'
 828
 829test_expect_success 'fetch with branches containing #' '
 830        mk_empty &&
 831        echo "..#second" > testrepo/.git/branches/branch2 &&
 832        (
 833                cd testrepo &&
 834                git fetch branch2 &&
 835                echo "$the_first_commit commit  refs/heads/branch2" >expect &&
 836                git for-each-ref refs/heads >actual &&
 837                test_cmp expect actual
 838        ) &&
 839        git checkout master
 840'
 841
 842test_expect_success 'push with branches' '
 843        mk_empty &&
 844        git checkout second &&
 845        echo "testrepo" > .git/branches/branch1 &&
 846        git push branch1 &&
 847        (
 848                cd testrepo &&
 849                echo "$the_first_commit commit  refs/heads/master" >expect &&
 850                git for-each-ref refs/heads >actual &&
 851                test_cmp expect actual
 852        )
 853'
 854
 855test_expect_success 'push with branches containing #' '
 856        mk_empty &&
 857        echo "testrepo#branch3" > .git/branches/branch2 &&
 858        git push branch2 &&
 859        (
 860                cd testrepo &&
 861                echo "$the_first_commit commit  refs/heads/branch3" >expect &&
 862                git for-each-ref refs/heads >actual &&
 863                test_cmp expect actual
 864        ) &&
 865        git checkout master
 866'
 867
 868test_expect_success 'push into aliased refs (consistent)' '
 869        mk_test heads/master &&
 870        mk_child child1 &&
 871        mk_child child2 &&
 872        (
 873                cd child1 &&
 874                git branch foo &&
 875                git symbolic-ref refs/heads/bar refs/heads/foo
 876                git config receive.denyCurrentBranch false
 877        ) &&
 878        (
 879                cd child2 &&
 880                >path2 &&
 881                git add path2 &&
 882                test_tick &&
 883                git commit -a -m child2 &&
 884                git branch foo &&
 885                git branch bar &&
 886                git push ../child1 foo bar
 887        )
 888'
 889
 890test_expect_success 'push into aliased refs (inconsistent)' '
 891        mk_test heads/master &&
 892        mk_child child1 &&
 893        mk_child child2 &&
 894        (
 895                cd child1 &&
 896                git branch foo &&
 897                git symbolic-ref refs/heads/bar refs/heads/foo
 898                git config receive.denyCurrentBranch false
 899        ) &&
 900        (
 901                cd child2 &&
 902                >path2 &&
 903                git add path2 &&
 904                test_tick &&
 905                git commit -a -m child2 &&
 906                git branch foo &&
 907                >path3 &&
 908                git add path3 &&
 909                test_tick &&
 910                git commit -a -m child2 &&
 911                git branch bar &&
 912                test_must_fail git push ../child1 foo bar 2>stderr &&
 913                grep "refusing inconsistent update" stderr
 914        )
 915'
 916
 917test_expect_success 'push requires --force to update lightweight tag' '
 918        mk_test heads/master &&
 919        mk_child child1 &&
 920        mk_child child2 &&
 921        (
 922                cd child1 &&
 923                git tag Tag &&
 924                git push ../child2 Tag &&
 925                git push ../child2 Tag &&
 926                >file1 &&
 927                git add file1 &&
 928                git commit -m "file1" &&
 929                git tag -f Tag &&
 930                test_must_fail git push ../child2 Tag &&
 931                git push --force ../child2 Tag &&
 932                git tag -f Tag &&
 933                test_must_fail git push ../child2 Tag HEAD~ &&
 934                git push --force ../child2 Tag
 935        )
 936'
 937
 938test_expect_success 'push --porcelain' '
 939        mk_empty &&
 940        echo >.git/foo  "To testrepo" &&
 941        echo >>.git/foo "*      refs/heads/master:refs/remotes/origin/master    [new branch]"  &&
 942        echo >>.git/foo "Done" &&
 943        git push >.git/bar --porcelain  testrepo refs/heads/master:refs/remotes/origin/master &&
 944        (
 945                cd testrepo &&
 946                echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 947                git for-each-ref refs/remotes/origin >actual &&
 948                test_cmp expect actual
 949        ) &&
 950        test_cmp .git/foo .git/bar
 951'
 952
 953test_expect_success 'push --porcelain bad url' '
 954        mk_empty &&
 955        test_must_fail git push >.git/bar --porcelain asdfasdfasd refs/heads/master:refs/remotes/origin/master &&
 956        test_must_fail grep -q Done .git/bar
 957'
 958
 959test_expect_success 'push --porcelain rejected' '
 960        mk_empty &&
 961        git push testrepo refs/heads/master:refs/remotes/origin/master &&
 962        (cd testrepo &&
 963                git reset --hard origin/master^
 964                git config receive.denyCurrentBranch true) &&
 965
 966        echo >.git/foo  "To testrepo"  &&
 967        echo >>.git/foo "!      refs/heads/master:refs/heads/master     [remote rejected] (branch is currently checked out)" &&
 968
 969        test_must_fail git push >.git/bar --porcelain  testrepo refs/heads/master:refs/heads/master &&
 970        test_cmp .git/foo .git/bar
 971'
 972
 973test_expect_success 'push --porcelain --dry-run rejected' '
 974        mk_empty &&
 975        git push testrepo refs/heads/master:refs/remotes/origin/master &&
 976        (cd testrepo &&
 977                git reset --hard origin/master
 978                git config receive.denyCurrentBranch true) &&
 979
 980        echo >.git/foo  "To testrepo"  &&
 981        echo >>.git/foo "!      refs/heads/master^:refs/heads/master    [rejected] (non-fast-forward)" &&
 982        echo >>.git/foo "Done" &&
 983
 984        test_must_fail git push >.git/bar --porcelain  --dry-run testrepo refs/heads/master^:refs/heads/master &&
 985        test_cmp .git/foo .git/bar
 986'
 987
 988test_expect_success 'push --prune' '
 989        mk_test heads/master heads/second heads/foo heads/bar &&
 990        git push --prune testrepo &&
 991        check_push_result $the_commit heads/master &&
 992        check_push_result $the_first_commit heads/second &&
 993        ! check_push_result $the_first_commit heads/foo heads/bar
 994'
 995
 996test_expect_success 'push --prune refspec' '
 997        mk_test tmp/master tmp/second tmp/foo tmp/bar &&
 998        git push --prune testrepo "refs/heads/*:refs/tmp/*" &&
 999        check_push_result $the_commit tmp/master &&
1000        check_push_result $the_first_commit tmp/second &&
1001        ! check_push_result $the_first_commit tmp/foo tmp/bar
1002'
1003
1004for configsection in transfer receive
1005do
1006        test_expect_success "push to update a ref hidden by $configsection.hiderefs" '
1007                mk_test heads/master hidden/one hidden/two hidden/three &&
1008                (
1009                        cd testrepo &&
1010                        git config $configsection.hiderefs refs/hidden
1011                ) &&
1012
1013                # push to unhidden ref succeeds normally
1014                git push testrepo master:refs/heads/master &&
1015                check_push_result $the_commit heads/master &&
1016
1017                # push to update a hidden ref should fail
1018                test_must_fail git push testrepo master:refs/hidden/one &&
1019                check_push_result $the_first_commit hidden/one &&
1020
1021                # push to delete a hidden ref should fail
1022                test_must_fail git push testrepo :refs/hidden/two &&
1023                check_push_result $the_first_commit hidden/two &&
1024
1025                # idempotent push to update a hidden ref should fail
1026                test_must_fail git push testrepo $the_first_commit:refs/hidden/three &&
1027                check_push_result $the_first_commit hidden/three
1028        '
1029done
1030
1031test_expect_success 'fetch exact SHA1' '
1032        mk_test heads/master hidden/one &&
1033        git push testrepo master:refs/hidden/one &&
1034        (
1035                cd testrepo &&
1036                git config transfer.hiderefs refs/hidden
1037        ) &&
1038        check_push_result $the_commit hidden/one &&
1039
1040        mk_child child &&
1041        (
1042                cd child &&
1043
1044                # make sure $the_commit does not exist here
1045                git repack -a -d &&
1046                git prune &&
1047                test_must_fail git cat-file -t $the_commit &&
1048
1049                # fetching the hidden object should fail by default
1050                test_must_fail git fetch -v ../testrepo $the_commit:refs/heads/copy &&
1051                test_must_fail git rev-parse --verify refs/heads/copy &&
1052
1053                # the server side can allow it to succeed
1054                (
1055                        cd ../testrepo &&
1056                        git config uploadpack.allowtipsha1inwant true
1057                ) &&
1058
1059                git fetch -v ../testrepo $the_commit:refs/heads/copy &&
1060                result=$(git rev-parse --verify refs/heads/copy) &&
1061                test "$the_commit" = "$result"
1062        )
1063'
1064
1065test_expect_success 'fetch follows tags by default' '
1066        mk_test heads/master &&
1067        rm -fr src dst &&
1068        git init src &&
1069        (
1070                cd src &&
1071                git pull ../testrepo master &&
1072                git tag -m "annotated" tag &&
1073                git for-each-ref >tmp1 &&
1074                (
1075                        cat tmp1
1076                        sed -n "s|refs/heads/master$|refs/remotes/origin/master|p" tmp1
1077                ) |
1078                sort -k 3 >../expect
1079        ) &&
1080        git init dst &&
1081        (
1082                cd dst &&
1083                git remote add origin ../src &&
1084                git config branch.master.remote origin &&
1085                git config branch.master.merge refs/heads/master &&
1086                git pull &&
1087                git for-each-ref >../actual
1088        ) &&
1089        test_cmp expect actual
1090'
1091
1092test_expect_success 'push does not follow tags by default' '
1093        mk_test heads/master &&
1094        rm -fr src dst &&
1095        git init src &&
1096        git init --bare dst &&
1097        (
1098                cd src &&
1099                git pull ../testrepo master &&
1100                git tag -m "annotated" tag &&
1101                git checkout -b another &&
1102                git commit --allow-empty -m "future commit" &&
1103                git tag -m "future" future &&
1104                git checkout master &&
1105                git for-each-ref refs/heads/master >../expect &&
1106                git push ../dst master
1107        ) &&
1108        (
1109                cd dst &&
1110                git for-each-ref >../actual
1111        ) &&
1112        test_cmp expect actual
1113'
1114
1115test_expect_success 'push --follow-tag only pushes relevant tags' '
1116        mk_test heads/master &&
1117        rm -fr src dst &&
1118        git init src &&
1119        git init --bare dst &&
1120        (
1121                cd src &&
1122                git pull ../testrepo master &&
1123                git tag -m "annotated" tag &&
1124                git checkout -b another &&
1125                git commit --allow-empty -m "future commit" &&
1126                git tag -m "future" future &&
1127                git checkout master &&
1128                git for-each-ref refs/heads/master refs/tags/tag >../expect
1129                git push --follow-tag ../dst master
1130        ) &&
1131        (
1132                cd dst &&
1133                git for-each-ref >../actual
1134        ) &&
1135        test_cmp expect actual
1136'
1137
1138test_done