t / t5516-fetch-push.shon commit init: use strbufs to store paths (9c28390)
   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        repo_name="$1"
  98        shift
  99
 100        (
 101                cd "$repo_name" &&
 102                echo "$1" >expect &&
 103                shift &&
 104                for ref in "$@"
 105                do
 106                        git show-ref -s --verify refs/$ref >actual &&
 107                        test_cmp expect actual ||
 108                        exit
 109                done &&
 110                git fsck --full
 111        )
 112}
 113
 114test_expect_success setup '
 115
 116        >path1 &&
 117        git add path1 &&
 118        test_tick &&
 119        git commit -a -m repo &&
 120        the_first_commit=$(git show-ref -s --verify refs/heads/master) &&
 121
 122        >path2 &&
 123        git add path2 &&
 124        test_tick &&
 125        git commit -a -m second &&
 126        the_commit=$(git show-ref -s --verify refs/heads/master)
 127
 128'
 129
 130test_expect_success 'fetch without wildcard' '
 131        mk_empty testrepo &&
 132        (
 133                cd testrepo &&
 134                git fetch .. refs/heads/master:refs/remotes/origin/master &&
 135
 136                echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 137                git for-each-ref refs/remotes/origin >actual &&
 138                test_cmp expect actual
 139        )
 140'
 141
 142test_expect_success 'fetch with wildcard' '
 143        mk_empty testrepo &&
 144        (
 145                cd testrepo &&
 146                git config remote.up.url .. &&
 147                git config remote.up.fetch "refs/heads/*:refs/remotes/origin/*" &&
 148                git fetch up &&
 149
 150                echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 151                git for-each-ref refs/remotes/origin >actual &&
 152                test_cmp expect actual
 153        )
 154'
 155
 156test_expect_success 'fetch with insteadOf' '
 157        mk_empty testrepo &&
 158        (
 159                TRASH=$(pwd)/ &&
 160                cd testrepo &&
 161                git config "url.$TRASH.insteadOf" trash/ &&
 162                git config remote.up.url trash/. &&
 163                git config remote.up.fetch "refs/heads/*:refs/remotes/origin/*" &&
 164                git fetch up &&
 165
 166                echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 167                git for-each-ref refs/remotes/origin >actual &&
 168                test_cmp expect actual
 169        )
 170'
 171
 172test_expect_success 'fetch with pushInsteadOf (should not rewrite)' '
 173        mk_empty testrepo &&
 174        (
 175                TRASH=$(pwd)/ &&
 176                cd testrepo &&
 177                git config "url.trash/.pushInsteadOf" "$TRASH" &&
 178                git config remote.up.url "$TRASH." &&
 179                git config remote.up.fetch "refs/heads/*:refs/remotes/origin/*" &&
 180                git fetch up &&
 181
 182                echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 183                git for-each-ref refs/remotes/origin >actual &&
 184                test_cmp expect actual
 185        )
 186'
 187
 188test_expect_success 'push without wildcard' '
 189        mk_empty testrepo &&
 190
 191        git push testrepo refs/heads/master:refs/remotes/origin/master &&
 192        (
 193                cd testrepo &&
 194                echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 195                git for-each-ref refs/remotes/origin >actual &&
 196                test_cmp expect actual
 197        )
 198'
 199
 200test_expect_success 'push with wildcard' '
 201        mk_empty testrepo &&
 202
 203        git push testrepo "refs/heads/*:refs/remotes/origin/*" &&
 204        (
 205                cd testrepo &&
 206                echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 207                git for-each-ref refs/remotes/origin >actual &&
 208                test_cmp expect actual
 209        )
 210'
 211
 212test_expect_success 'push with insteadOf' '
 213        mk_empty testrepo &&
 214        TRASH="$(pwd)/" &&
 215        test_config "url.$TRASH.insteadOf" trash/ &&
 216        git push trash/testrepo refs/heads/master:refs/remotes/origin/master &&
 217        (
 218                cd testrepo &&
 219                echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 220                git for-each-ref refs/remotes/origin >actual &&
 221                test_cmp expect actual
 222        )
 223'
 224
 225test_expect_success 'push with pushInsteadOf' '
 226        mk_empty testrepo &&
 227        TRASH="$(pwd)/" &&
 228        test_config "url.$TRASH.pushInsteadOf" trash/ &&
 229        git push trash/testrepo refs/heads/master:refs/remotes/origin/master &&
 230        (
 231                cd testrepo &&
 232                echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 233                git for-each-ref refs/remotes/origin >actual &&
 234                test_cmp expect actual
 235        )
 236'
 237
 238test_expect_success 'push with pushInsteadOf and explicit pushurl (pushInsteadOf should not rewrite)' '
 239        mk_empty testrepo &&
 240        test_config "url.trash2/.pushInsteadOf" testrepo/ &&
 241        test_config "url.trash3/.pushInsteadOf" trash/wrong &&
 242        test_config remote.r.url trash/wrong &&
 243        test_config remote.r.pushurl "testrepo/" &&
 244        git push r refs/heads/master:refs/remotes/origin/master &&
 245        (
 246                cd testrepo &&
 247                echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 248                git for-each-ref refs/remotes/origin >actual &&
 249                test_cmp expect actual
 250        )
 251'
 252
 253test_expect_success 'push with matching heads' '
 254
 255        mk_test testrepo heads/master &&
 256        git push testrepo : &&
 257        check_push_result testrepo $the_commit heads/master
 258
 259'
 260
 261test_expect_success 'push with matching heads on the command line' '
 262
 263        mk_test testrepo heads/master &&
 264        git push testrepo : &&
 265        check_push_result testrepo $the_commit heads/master
 266
 267'
 268
 269test_expect_success 'failed (non-fast-forward) push with matching heads' '
 270
 271        mk_test testrepo heads/master &&
 272        git push testrepo : &&
 273        git commit --amend -massaged &&
 274        test_must_fail git push testrepo &&
 275        check_push_result testrepo $the_commit heads/master &&
 276        git reset --hard $the_commit
 277
 278'
 279
 280test_expect_success 'push --force with matching heads' '
 281
 282        mk_test testrepo heads/master &&
 283        git push testrepo : &&
 284        git commit --amend -massaged &&
 285        git push --force testrepo : &&
 286        ! check_push_result testrepo $the_commit heads/master &&
 287        git reset --hard $the_commit
 288
 289'
 290
 291test_expect_success 'push with matching heads and forced update' '
 292
 293        mk_test testrepo heads/master &&
 294        git push testrepo : &&
 295        git commit --amend -massaged &&
 296        git push testrepo +: &&
 297        ! check_push_result testrepo $the_commit heads/master &&
 298        git reset --hard $the_commit
 299
 300'
 301
 302test_expect_success 'push with no ambiguity (1)' '
 303
 304        mk_test testrepo heads/master &&
 305        git push testrepo master:master &&
 306        check_push_result testrepo $the_commit heads/master
 307
 308'
 309
 310test_expect_success 'push with no ambiguity (2)' '
 311
 312        mk_test testrepo remotes/origin/master &&
 313        git push testrepo master:origin/master &&
 314        check_push_result testrepo $the_commit remotes/origin/master
 315
 316'
 317
 318test_expect_success 'push with colon-less refspec, no ambiguity' '
 319
 320        mk_test testrepo heads/master heads/t/master &&
 321        git branch -f t/master master &&
 322        git push testrepo master &&
 323        check_push_result testrepo $the_commit heads/master &&
 324        check_push_result testrepo $the_first_commit heads/t/master
 325
 326'
 327
 328test_expect_success 'push with weak ambiguity (1)' '
 329
 330        mk_test testrepo heads/master remotes/origin/master &&
 331        git push testrepo master:master &&
 332        check_push_result testrepo $the_commit heads/master &&
 333        check_push_result testrepo $the_first_commit remotes/origin/master
 334
 335'
 336
 337test_expect_success 'push with weak ambiguity (2)' '
 338
 339        mk_test testrepo heads/master remotes/origin/master remotes/another/master &&
 340        git push testrepo master:master &&
 341        check_push_result testrepo $the_commit heads/master &&
 342        check_push_result testrepo $the_first_commit remotes/origin/master remotes/another/master
 343
 344'
 345
 346test_expect_success 'push with ambiguity' '
 347
 348        mk_test testrepo heads/frotz tags/frotz &&
 349        test_must_fail git push testrepo master:frotz &&
 350        check_push_result testrepo $the_first_commit heads/frotz tags/frotz
 351
 352'
 353
 354test_expect_success 'push with colon-less refspec (1)' '
 355
 356        mk_test testrepo heads/frotz tags/frotz &&
 357        git branch -f frotz master &&
 358        git push testrepo frotz &&
 359        check_push_result testrepo $the_commit heads/frotz &&
 360        check_push_result testrepo $the_first_commit tags/frotz
 361
 362'
 363
 364test_expect_success 'push with colon-less refspec (2)' '
 365
 366        mk_test testrepo heads/frotz tags/frotz &&
 367        if git show-ref --verify -q refs/heads/frotz
 368        then
 369                git branch -D frotz
 370        fi &&
 371        git tag -f frotz &&
 372        git push -f testrepo frotz &&
 373        check_push_result testrepo $the_commit tags/frotz &&
 374        check_push_result testrepo $the_first_commit heads/frotz
 375
 376'
 377
 378test_expect_success 'push with colon-less refspec (3)' '
 379
 380        mk_test testrepo &&
 381        if git show-ref --verify -q refs/tags/frotz
 382        then
 383                git tag -d frotz
 384        fi &&
 385        git branch -f frotz master &&
 386        git push testrepo frotz &&
 387        check_push_result testrepo $the_commit heads/frotz &&
 388        test 1 = $( cd testrepo && git show-ref | wc -l )
 389'
 390
 391test_expect_success 'push with colon-less refspec (4)' '
 392
 393        mk_test testrepo &&
 394        if git show-ref --verify -q refs/heads/frotz
 395        then
 396                git branch -D frotz
 397        fi &&
 398        git tag -f frotz &&
 399        git push testrepo frotz &&
 400        check_push_result testrepo $the_commit tags/frotz &&
 401        test 1 = $( cd testrepo && git show-ref | wc -l )
 402
 403'
 404
 405test_expect_success 'push head with non-existent, incomplete dest' '
 406
 407        mk_test testrepo &&
 408        git push testrepo master:branch &&
 409        check_push_result testrepo $the_commit heads/branch
 410
 411'
 412
 413test_expect_success 'push tag with non-existent, incomplete dest' '
 414
 415        mk_test testrepo &&
 416        git tag -f v1.0 &&
 417        git push testrepo v1.0:tag &&
 418        check_push_result testrepo $the_commit tags/tag
 419
 420'
 421
 422test_expect_success 'push sha1 with non-existent, incomplete dest' '
 423
 424        mk_test testrepo &&
 425        test_must_fail git push testrepo `git rev-parse master`:foo
 426
 427'
 428
 429test_expect_success 'push ref expression with non-existent, incomplete dest' '
 430
 431        mk_test testrepo &&
 432        test_must_fail git push testrepo master^:branch
 433
 434'
 435
 436test_expect_success 'push with HEAD' '
 437
 438        mk_test testrepo heads/master &&
 439        git checkout master &&
 440        git push testrepo HEAD &&
 441        check_push_result testrepo $the_commit heads/master
 442
 443'
 444
 445test_expect_success 'push with HEAD nonexisting at remote' '
 446
 447        mk_test testrepo heads/master &&
 448        git checkout -b local master &&
 449        git push testrepo HEAD &&
 450        check_push_result testrepo $the_commit heads/local
 451'
 452
 453test_expect_success 'push with +HEAD' '
 454
 455        mk_test testrepo heads/master &&
 456        git checkout master &&
 457        git branch -D local &&
 458        git checkout -b local &&
 459        git push testrepo master local &&
 460        check_push_result testrepo $the_commit heads/master &&
 461        check_push_result testrepo $the_commit heads/local &&
 462
 463        # Without force rewinding should fail
 464        git reset --hard HEAD^ &&
 465        test_must_fail git push testrepo HEAD &&
 466        check_push_result testrepo $the_commit heads/local &&
 467
 468        # With force rewinding should succeed
 469        git push testrepo +HEAD &&
 470        check_push_result testrepo $the_first_commit heads/local
 471
 472'
 473
 474test_expect_success 'push HEAD with non-existent, incomplete dest' '
 475
 476        mk_test testrepo &&
 477        git checkout master &&
 478        git push testrepo HEAD:branch &&
 479        check_push_result testrepo $the_commit heads/branch
 480
 481'
 482
 483test_expect_success 'push with config remote.*.push = HEAD' '
 484
 485        mk_test testrepo heads/local &&
 486        git checkout master &&
 487        git branch -f local $the_commit &&
 488        (
 489                cd testrepo &&
 490                git checkout local &&
 491                git reset --hard $the_first_commit
 492        ) &&
 493        test_config remote.there.url testrepo &&
 494        test_config remote.there.push HEAD &&
 495        test_config branch.master.remote there &&
 496        git push &&
 497        check_push_result testrepo $the_commit heads/master &&
 498        check_push_result testrepo $the_first_commit heads/local
 499'
 500
 501test_expect_success 'push with remote.pushdefault' '
 502        mk_test up_repo heads/master &&
 503        mk_test down_repo heads/master &&
 504        test_config remote.up.url up_repo &&
 505        test_config remote.down.url down_repo &&
 506        test_config branch.master.remote up &&
 507        test_config remote.pushdefault down &&
 508        test_config push.default matching &&
 509        git push &&
 510        check_push_result up_repo $the_first_commit heads/master &&
 511        check_push_result down_repo $the_commit heads/master
 512'
 513
 514test_expect_success 'push with config remote.*.pushurl' '
 515
 516        mk_test testrepo heads/master &&
 517        git checkout master &&
 518        test_config remote.there.url test2repo &&
 519        test_config remote.there.pushurl testrepo &&
 520        git push there : &&
 521        check_push_result testrepo $the_commit heads/master
 522'
 523
 524test_expect_success 'push with config branch.*.pushremote' '
 525        mk_test up_repo heads/master &&
 526        mk_test side_repo heads/master &&
 527        mk_test down_repo heads/master &&
 528        test_config remote.up.url up_repo &&
 529        test_config remote.pushdefault side_repo &&
 530        test_config remote.down.url down_repo &&
 531        test_config branch.master.remote up &&
 532        test_config branch.master.pushremote down &&
 533        test_config push.default matching &&
 534        git push &&
 535        check_push_result up_repo $the_first_commit heads/master &&
 536        check_push_result side_repo $the_first_commit heads/master &&
 537        check_push_result down_repo $the_commit heads/master
 538'
 539
 540test_expect_success 'branch.*.pushremote config order is irrelevant' '
 541        mk_test one_repo heads/master &&
 542        mk_test two_repo heads/master &&
 543        test_config remote.one.url one_repo &&
 544        test_config remote.two.url two_repo &&
 545        test_config branch.master.pushremote two_repo &&
 546        test_config remote.pushdefault one_repo &&
 547        test_config push.default matching &&
 548        git push &&
 549        check_push_result one_repo $the_first_commit heads/master &&
 550        check_push_result two_repo $the_commit heads/master
 551'
 552
 553test_expect_success 'push with dry-run' '
 554
 555        mk_test testrepo heads/master &&
 556        (
 557                cd testrepo &&
 558                old_commit=$(git show-ref -s --verify refs/heads/master)
 559        ) &&
 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=$_z40 &&
 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                $_z40 $_z40 refs/heads/master
 676                EOF
 677
 678                cat >update.expect <<-EOF &&
 679                refs/heads/master $_z40 $_z40
 680                EOF
 681
 682                cat >post-receive.expect <<-EOF &&
 683                $_z40 $_z40 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                $_z40 $_z40 refs/heads/nonexistent
 707                EOF
 708
 709                cat >update.expect <<-EOF &&
 710                refs/heads/master $orgmaster $newmaster
 711                refs/heads/nonexistent $_z40 $_z40
 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                $_z40 $_z40 refs/heads/nonexistent
 736                EOF
 737
 738                cat >update.expect <<-EOF &&
 739                refs/heads/nonexistent $_z40 $_z40
 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=$_z40 &&
 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                $_z40 $_z40 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 $_z40 $_z40
 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_expect_success 'push requires --force to update lightweight tag' '
 969        mk_test testrepo heads/master &&
 970        mk_child testrepo child1 &&
 971        mk_child testrepo child2 &&
 972        (
 973                cd child1 &&
 974                git tag Tag &&
 975                git push ../child2 Tag &&
 976                git push ../child2 Tag &&
 977                >file1 &&
 978                git add file1 &&
 979                git commit -m "file1" &&
 980                git tag -f Tag &&
 981                test_must_fail git push ../child2 Tag &&
 982                git push --force ../child2 Tag &&
 983                git tag -f Tag &&
 984                test_must_fail git push ../child2 Tag HEAD~ &&
 985                git push --force ../child2 Tag
 986        )
 987'
 988
 989test_expect_success 'push --porcelain' '
 990        mk_empty testrepo &&
 991        echo >.git/foo  "To testrepo" &&
 992        echo >>.git/foo "*      refs/heads/master:refs/remotes/origin/master    [new branch]"  &&
 993        echo >>.git/foo "Done" &&
 994        git push >.git/bar --porcelain  testrepo refs/heads/master:refs/remotes/origin/master &&
 995        (
 996                cd testrepo &&
 997                echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 998                git for-each-ref refs/remotes/origin >actual &&
 999                test_cmp expect actual
1000        ) &&
1001        test_cmp .git/foo .git/bar
1002'
1003
1004test_expect_success 'push --porcelain bad url' '
1005        mk_empty testrepo &&
1006        test_must_fail git push >.git/bar --porcelain asdfasdfasd refs/heads/master:refs/remotes/origin/master &&
1007        test_must_fail grep -q Done .git/bar
1008'
1009
1010test_expect_success 'push --porcelain rejected' '
1011        mk_empty testrepo &&
1012        git push testrepo refs/heads/master:refs/remotes/origin/master &&
1013        (cd testrepo &&
1014                git reset --hard origin/master^
1015                git config receive.denyCurrentBranch true) &&
1016
1017        echo >.git/foo  "To testrepo"  &&
1018        echo >>.git/foo "!      refs/heads/master:refs/heads/master     [remote rejected] (branch is currently checked out)" &&
1019
1020        test_must_fail git push >.git/bar --porcelain  testrepo refs/heads/master:refs/heads/master &&
1021        test_cmp .git/foo .git/bar
1022'
1023
1024test_expect_success 'push --porcelain --dry-run rejected' '
1025        mk_empty testrepo &&
1026        git push testrepo refs/heads/master:refs/remotes/origin/master &&
1027        (cd testrepo &&
1028                git reset --hard origin/master
1029                git config receive.denyCurrentBranch true) &&
1030
1031        echo >.git/foo  "To testrepo"  &&
1032        echo >>.git/foo "!      refs/heads/master^:refs/heads/master    [rejected] (non-fast-forward)" &&
1033        echo >>.git/foo "Done" &&
1034
1035        test_must_fail git push >.git/bar --porcelain  --dry-run testrepo refs/heads/master^:refs/heads/master &&
1036        test_cmp .git/foo .git/bar
1037'
1038
1039test_expect_success 'push --prune' '
1040        mk_test testrepo heads/master heads/second heads/foo heads/bar &&
1041        git push --prune testrepo : &&
1042        check_push_result testrepo $the_commit heads/master &&
1043        check_push_result testrepo $the_first_commit heads/second &&
1044        ! check_push_result testrepo $the_first_commit heads/foo heads/bar
1045'
1046
1047test_expect_success 'push --prune refspec' '
1048        mk_test testrepo tmp/master tmp/second tmp/foo tmp/bar &&
1049        git push --prune testrepo "refs/heads/*:refs/tmp/*" &&
1050        check_push_result testrepo $the_commit tmp/master &&
1051        check_push_result testrepo $the_first_commit tmp/second &&
1052        ! check_push_result testrepo $the_first_commit tmp/foo tmp/bar
1053'
1054
1055for configsection in transfer receive
1056do
1057        test_expect_success "push to update a ref hidden by $configsection.hiderefs" '
1058                mk_test testrepo heads/master hidden/one hidden/two hidden/three &&
1059                (
1060                        cd testrepo &&
1061                        git config $configsection.hiderefs refs/hidden
1062                ) &&
1063
1064                # push to unhidden ref succeeds normally
1065                git push testrepo master:refs/heads/master &&
1066                check_push_result testrepo $the_commit heads/master &&
1067
1068                # push to update a hidden ref should fail
1069                test_must_fail git push testrepo master:refs/hidden/one &&
1070                check_push_result testrepo $the_first_commit hidden/one &&
1071
1072                # push to delete a hidden ref should fail
1073                test_must_fail git push testrepo :refs/hidden/two &&
1074                check_push_result testrepo $the_first_commit hidden/two &&
1075
1076                # idempotent push to update a hidden ref should fail
1077                test_must_fail git push testrepo $the_first_commit:refs/hidden/three &&
1078                check_push_result testrepo $the_first_commit hidden/three
1079        '
1080done
1081
1082test_expect_success 'fetch exact SHA1' '
1083        mk_test testrepo heads/master hidden/one &&
1084        git push testrepo master:refs/hidden/one &&
1085        (
1086                cd testrepo &&
1087                git config transfer.hiderefs refs/hidden
1088        ) &&
1089        check_push_result testrepo $the_commit hidden/one &&
1090
1091        mk_child testrepo child &&
1092        (
1093                cd child &&
1094
1095                # make sure $the_commit does not exist here
1096                git repack -a -d &&
1097                git prune &&
1098                test_must_fail git cat-file -t $the_commit &&
1099
1100                # fetching the hidden object should fail by default
1101                test_must_fail git fetch -v ../testrepo $the_commit:refs/heads/copy &&
1102                test_must_fail git rev-parse --verify refs/heads/copy &&
1103
1104                # the server side can allow it to succeed
1105                (
1106                        cd ../testrepo &&
1107                        git config uploadpack.allowtipsha1inwant true
1108                ) &&
1109
1110                git fetch -v ../testrepo $the_commit:refs/heads/copy master:refs/heads/extra &&
1111                cat >expect <<-EOF &&
1112                $the_commit
1113                $the_first_commit
1114                EOF
1115                {
1116                        git rev-parse --verify refs/heads/copy &&
1117                        git rev-parse --verify refs/heads/extra
1118                } >actual &&
1119                test_cmp expect actual
1120        )
1121'
1122
1123for configallowtipsha1inwant in true false
1124do
1125        test_expect_success "shallow fetch reachable SHA1 (but not a ref), allowtipsha1inwant=$configallowtipsha1inwant" '
1126                mk_empty testrepo &&
1127                (
1128                        cd testrepo &&
1129                        git config uploadpack.allowtipsha1inwant $configallowtipsha1inwant &&
1130                        git commit --allow-empty -m foo &&
1131                        git commit --allow-empty -m bar
1132                ) &&
1133                SHA1=$(git --git-dir=testrepo/.git rev-parse HEAD^) &&
1134                mk_empty shallow &&
1135                (
1136                        cd shallow &&
1137                        test_must_fail git fetch --depth=1 ../testrepo/.git $SHA1 &&
1138                        git --git-dir=../testrepo/.git config uploadpack.allowreachablesha1inwant true &&
1139                        git fetch --depth=1 ../testrepo/.git $SHA1 &&
1140                        git cat-file commit $SHA1
1141                )
1142        '
1143
1144        test_expect_success "deny fetch unreachable SHA1, allowtipsha1inwant=$configallowtipsha1inwant" '
1145                mk_empty testrepo &&
1146                (
1147                        cd testrepo &&
1148                        git config uploadpack.allowtipsha1inwant $configallowtipsha1inwant &&
1149                        git commit --allow-empty -m foo &&
1150                        git commit --allow-empty -m bar &&
1151                        git commit --allow-empty -m xyz
1152                ) &&
1153                SHA1_1=$(git --git-dir=testrepo/.git rev-parse HEAD^^) &&
1154                SHA1_2=$(git --git-dir=testrepo/.git rev-parse HEAD^) &&
1155                SHA1_3=$(git --git-dir=testrepo/.git rev-parse HEAD) &&
1156                (
1157                        cd testrepo &&
1158                        git reset --hard $SHA1_2 &&
1159                        git cat-file commit $SHA1_1 &&
1160                        git cat-file commit $SHA1_3
1161                ) &&
1162                mk_empty shallow &&
1163                (
1164                        cd shallow &&
1165                        test_must_fail git fetch ../testrepo/.git $SHA1_3 &&
1166                        test_must_fail git fetch ../testrepo/.git $SHA1_1 &&
1167                        git --git-dir=../testrepo/.git config uploadpack.allowreachablesha1inwant true &&
1168                        git fetch ../testrepo/.git $SHA1_1 &&
1169                        git cat-file commit $SHA1_1 &&
1170                        test_must_fail git cat-file commit $SHA1_2 &&
1171                        git fetch ../testrepo/.git $SHA1_2 &&
1172                        git cat-file commit $SHA1_2 &&
1173                        test_must_fail git fetch ../testrepo/.git $SHA1_3
1174                )
1175        '
1176done
1177
1178test_expect_success 'fetch follows tags by default' '
1179        mk_test testrepo heads/master &&
1180        rm -fr src dst &&
1181        git init src &&
1182        (
1183                cd src &&
1184                git pull ../testrepo master &&
1185                git tag -m "annotated" tag &&
1186                git for-each-ref >tmp1 &&
1187                (
1188                        cat tmp1
1189                        sed -n "s|refs/heads/master$|refs/remotes/origin/master|p" tmp1
1190                ) |
1191                sort -k 3 >../expect
1192        ) &&
1193        git init dst &&
1194        (
1195                cd dst &&
1196                git remote add origin ../src &&
1197                git config branch.master.remote origin &&
1198                git config branch.master.merge refs/heads/master &&
1199                git pull &&
1200                git for-each-ref >../actual
1201        ) &&
1202        test_cmp expect actual
1203'
1204
1205test_expect_success 'pushing a specific ref applies remote.$name.push as refmap' '
1206        mk_test testrepo heads/master &&
1207        rm -fr src dst &&
1208        git init src &&
1209        git init --bare dst &&
1210        (
1211                cd src &&
1212                git pull ../testrepo master &&
1213                git branch next &&
1214                git config remote.dst.url ../dst &&
1215                git config remote.dst.push "+refs/heads/*:refs/remotes/src/*" &&
1216                git push dst master &&
1217                git show-ref refs/heads/master |
1218                sed -e "s|refs/heads/|refs/remotes/src/|" >../dst/expect
1219        ) &&
1220        (
1221                cd dst &&
1222                test_must_fail git show-ref refs/heads/next &&
1223                test_must_fail git show-ref refs/heads/master &&
1224                git show-ref refs/remotes/src/master >actual
1225        ) &&
1226        test_cmp dst/expect dst/actual
1227'
1228
1229test_expect_success 'with no remote.$name.push, it is not used as refmap' '
1230        mk_test testrepo heads/master &&
1231        rm -fr src dst &&
1232        git init src &&
1233        git init --bare dst &&
1234        (
1235                cd src &&
1236                git pull ../testrepo master &&
1237                git branch next &&
1238                git config remote.dst.url ../dst &&
1239                git config push.default matching &&
1240                git push dst master &&
1241                git show-ref refs/heads/master >../dst/expect
1242        ) &&
1243        (
1244                cd dst &&
1245                test_must_fail git show-ref refs/heads/next &&
1246                git show-ref refs/heads/master >actual
1247        ) &&
1248        test_cmp dst/expect dst/actual
1249'
1250
1251test_expect_success 'with no remote.$name.push, upstream mapping is used' '
1252        mk_test testrepo heads/master &&
1253        rm -fr src dst &&
1254        git init src &&
1255        git init --bare dst &&
1256        (
1257                cd src &&
1258                git pull ../testrepo master &&
1259                git branch next &&
1260                git config remote.dst.url ../dst &&
1261                git config remote.dst.fetch "+refs/heads/*:refs/remotes/dst/*" &&
1262                git config push.default upstream &&
1263
1264                git config branch.master.merge refs/heads/trunk &&
1265                git config branch.master.remote dst &&
1266
1267                git push dst master &&
1268                git show-ref refs/heads/master |
1269                sed -e "s|refs/heads/master|refs/heads/trunk|" >../dst/expect
1270        ) &&
1271        (
1272                cd dst &&
1273                test_must_fail git show-ref refs/heads/master &&
1274                test_must_fail git show-ref refs/heads/next &&
1275                git show-ref refs/heads/trunk >actual
1276        ) &&
1277        test_cmp dst/expect dst/actual
1278'
1279
1280test_expect_success 'push does not follow tags by default' '
1281        mk_test testrepo heads/master &&
1282        rm -fr src dst &&
1283        git init src &&
1284        git init --bare dst &&
1285        (
1286                cd src &&
1287                git pull ../testrepo master &&
1288                git tag -m "annotated" tag &&
1289                git checkout -b another &&
1290                git commit --allow-empty -m "future commit" &&
1291                git tag -m "future" future &&
1292                git checkout master &&
1293                git for-each-ref refs/heads/master >../expect &&
1294                git push ../dst master
1295        ) &&
1296        (
1297                cd dst &&
1298                git for-each-ref >../actual
1299        ) &&
1300        test_cmp expect actual
1301'
1302
1303test_expect_success 'push --follow-tag only pushes relevant tags' '
1304        mk_test testrepo heads/master &&
1305        rm -fr src dst &&
1306        git init src &&
1307        git init --bare dst &&
1308        (
1309                cd src &&
1310                git pull ../testrepo master &&
1311                git tag -m "annotated" tag &&
1312                git checkout -b another &&
1313                git commit --allow-empty -m "future commit" &&
1314                git tag -m "future" future &&
1315                git checkout master &&
1316                git for-each-ref refs/heads/master refs/tags/tag >../expect
1317                git push --follow-tag ../dst master
1318        ) &&
1319        (
1320                cd dst &&
1321                git for-each-ref >../actual
1322        ) &&
1323        test_cmp expect actual
1324'
1325
1326test_expect_success 'push --no-thin must produce non-thin pack' '
1327        cat >>path1 <<\EOF &&
1328keep base version of path1 big enough, compared to the new changes
1329later, in order to pass size heuristics in
1330builtin/pack-objects.c:try_delta()
1331EOF
1332        git commit -am initial &&
1333        git init no-thin &&
1334        git --git-dir=no-thin/.git config receive.unpacklimit 0 &&
1335        git push no-thin/.git refs/heads/master:refs/heads/foo &&
1336        echo modified >> path1 &&
1337        git commit -am modified &&
1338        git repack -adf &&
1339        rcvpck="git receive-pack --reject-thin-pack-for-testing" &&
1340        git push --no-thin --receive-pack="$rcvpck" no-thin/.git refs/heads/master:refs/heads/foo
1341'
1342
1343test_expect_success 'pushing a tag pushes the tagged object' '
1344        rm -rf dst.git &&
1345        blob=$(echo unreferenced | git hash-object -w --stdin) &&
1346        git tag -m foo tag-of-blob $blob &&
1347        git init --bare dst.git &&
1348        git push dst.git tag-of-blob &&
1349        # the receiving index-pack should have noticed
1350        # any problems, but we double check
1351        echo unreferenced >expect &&
1352        git --git-dir=dst.git cat-file blob tag-of-blob >actual &&
1353        test_cmp expect actual
1354'
1355
1356test_expect_success 'push into bare respects core.logallrefupdates' '
1357        rm -rf dst.git &&
1358        git init --bare dst.git &&
1359        git -C dst.git config core.logallrefupdates true &&
1360
1361        # double push to test both with and without
1362        # the actual pack transfer
1363        git push dst.git master:one &&
1364        echo "one@{0} push" >expect &&
1365        git -C dst.git log -g --format="%gd %gs" one >actual &&
1366        test_cmp expect actual &&
1367
1368        git push dst.git master:two &&
1369        echo "two@{0} push" >expect &&
1370        git -C dst.git log -g --format="%gd %gs" two >actual &&
1371        test_cmp expect actual
1372'
1373
1374test_expect_success 'fetch into bare respects core.logallrefupdates' '
1375        rm -rf dst.git &&
1376        git init --bare dst.git &&
1377        (
1378                cd dst.git &&
1379                git config core.logallrefupdates true &&
1380
1381                # as above, we double-fetch to test both
1382                # with and without pack transfer
1383                git fetch .. master:one &&
1384                echo "one@{0} fetch .. master:one: storing head" >expect &&
1385                git log -g --format="%gd %gs" one >actual &&
1386                test_cmp expect actual &&
1387
1388                git fetch .. master:two &&
1389                echo "two@{0} fetch .. master:two: storing head" >expect &&
1390                git log -g --format="%gd %gs" two >actual &&
1391                test_cmp expect actual
1392        )
1393'
1394
1395test_expect_success 'receive.denyCurrentBranch = updateInstead' '
1396        git push testrepo master &&
1397        (
1398                cd testrepo &&
1399                git reset --hard &&
1400                git config receive.denyCurrentBranch updateInstead
1401        ) &&
1402        test_commit third path2 &&
1403
1404        # Try pushing into a repository with pristine working tree
1405        git push testrepo master &&
1406        (
1407                cd testrepo &&
1408                git update-index -q --refresh &&
1409                git diff-files --quiet -- &&
1410                git diff-index --quiet --cached HEAD -- &&
1411                test third = "$(cat path2)" &&
1412                test $(git -C .. rev-parse HEAD) = $(git rev-parse HEAD)
1413        ) &&
1414
1415        # Try pushing into a repository with working tree needing a refresh
1416        (
1417                cd testrepo &&
1418                git reset --hard HEAD^ &&
1419                test $(git -C .. rev-parse HEAD^) = $(git rev-parse HEAD) &&
1420                test-chmtime +100 path1
1421        ) &&
1422        git push testrepo master &&
1423        (
1424                cd testrepo &&
1425                git update-index -q --refresh &&
1426                git diff-files --quiet -- &&
1427                git diff-index --quiet --cached HEAD -- &&
1428                test_cmp ../path1 path1 &&
1429                test third = "$(cat path2)" &&
1430                test $(git -C .. rev-parse HEAD) = $(git rev-parse HEAD)
1431        ) &&
1432
1433        # Update what is to be pushed
1434        test_commit fourth path2 &&
1435
1436        # Try pushing into a repository with a dirty working tree
1437        # (1) the working tree updated
1438        (
1439                cd testrepo &&
1440                echo changed >path1
1441        ) &&
1442        test_must_fail git push testrepo master &&
1443        (
1444                cd testrepo &&
1445                test $(git -C .. rev-parse HEAD^) = $(git rev-parse HEAD) &&
1446                git diff --quiet --cached &&
1447                test changed = "$(cat path1)"
1448        ) &&
1449
1450        # (2) the index updated
1451        (
1452                cd testrepo &&
1453                echo changed >path1 &&
1454                git add path1
1455        ) &&
1456        test_must_fail git push testrepo master &&
1457        (
1458                cd testrepo &&
1459                test $(git -C .. rev-parse HEAD^) = $(git rev-parse HEAD) &&
1460                git diff --quiet &&
1461                test changed = "$(cat path1)"
1462        ) &&
1463
1464        # Introduce a new file in the update
1465        test_commit fifth path3 &&
1466
1467        # (3) the working tree has an untracked file that would interfere
1468        (
1469                cd testrepo &&
1470                git reset --hard &&
1471                echo changed >path3
1472        ) &&
1473        test_must_fail git push testrepo master &&
1474        (
1475                cd testrepo &&
1476                test $(git -C .. rev-parse HEAD^^) = $(git rev-parse HEAD) &&
1477                git diff --quiet &&
1478                git diff --quiet --cached &&
1479                test changed = "$(cat path3)"
1480        ) &&
1481
1482        # (4) the target changes to what gets pushed but it still is a change
1483        (
1484                cd testrepo &&
1485                git reset --hard &&
1486                echo fifth >path3 &&
1487                git add path3
1488        ) &&
1489        test_must_fail git push testrepo master &&
1490        (
1491                cd testrepo &&
1492                test $(git -C .. rev-parse HEAD^^) = $(git rev-parse HEAD) &&
1493                git diff --quiet &&
1494                test fifth = "$(cat path3)"
1495        ) &&
1496
1497        # (5) push into void
1498        rm -fr void &&
1499        git init void &&
1500        (
1501                cd void &&
1502                git config receive.denyCurrentBranch updateInstead
1503        ) &&
1504        git push void master &&
1505        (
1506                cd void &&
1507                test $(git -C .. rev-parse master) = $(git rev-parse HEAD) &&
1508                git diff --quiet &&
1509                git diff --cached --quiet
1510        )
1511'
1512
1513test_expect_success 'updateInstead with push-to-checkout hook' '
1514        rm -fr testrepo &&
1515        git init testrepo &&
1516        (
1517                cd testrepo &&
1518                git pull .. master &&
1519                git reset --hard HEAD^^ &&
1520                git tag initial &&
1521                git config receive.denyCurrentBranch updateInstead &&
1522                write_script .git/hooks/push-to-checkout <<-\EOF
1523                echo >&2 updating from $(git rev-parse HEAD)
1524                echo >&2 updating to "$1"
1525
1526                git update-index -q --refresh &&
1527                git read-tree -u -m HEAD "$1" || {
1528                        status=$?
1529                        echo >&2 read-tree failed
1530                        exit $status
1531                }
1532                EOF
1533        ) &&
1534
1535        # Try pushing into a pristine
1536        git push testrepo master &&
1537        (
1538                cd testrepo &&
1539                git diff --quiet &&
1540                git diff HEAD --quiet &&
1541                test $(git -C .. rev-parse HEAD) = $(git rev-parse HEAD)
1542        ) &&
1543
1544        # Try pushing into a repository with conflicting change
1545        (
1546                cd testrepo &&
1547                git reset --hard initial &&
1548                echo conflicting >path2
1549        ) &&
1550        test_must_fail git push testrepo master &&
1551        (
1552                cd testrepo &&
1553                test $(git rev-parse initial) = $(git rev-parse HEAD) &&
1554                test conflicting = "$(cat path2)" &&
1555                git diff-index --quiet --cached HEAD
1556        ) &&
1557
1558        # Try pushing into a repository with unrelated change
1559        (
1560                cd testrepo &&
1561                git reset --hard initial &&
1562                echo unrelated >path1 &&
1563                echo irrelevant >path5 &&
1564                git add path5
1565        ) &&
1566        git push testrepo master &&
1567        (
1568                cd testrepo &&
1569                test "$(cat path1)" = unrelated &&
1570                test "$(cat path5)" = irrelevant &&
1571                test "$(git diff --name-only --cached HEAD)" = path5 &&
1572                test $(git -C .. rev-parse HEAD) = $(git rev-parse HEAD)
1573        ) &&
1574
1575        # push into void
1576        rm -fr void &&
1577        git init void &&
1578        (
1579                cd void &&
1580                git config receive.denyCurrentBranch updateInstead &&
1581                write_script .git/hooks/push-to-checkout <<-\EOF
1582                if git rev-parse --quiet --verify HEAD
1583                then
1584                        has_head=yes
1585                        echo >&2 updating from $(git rev-parse HEAD)
1586                else
1587                        has_head=no
1588                        echo >&2 pushing into void
1589                fi
1590                echo >&2 updating to "$1"
1591
1592                git update-index -q --refresh &&
1593                case "$has_head" in
1594                yes)
1595                        git read-tree -u -m HEAD "$1" ;;
1596                no)
1597                        git read-tree -u -m "$1" ;;
1598                esac || {
1599                        status=$?
1600                        echo >&2 read-tree failed
1601                        exit $status
1602                }
1603                EOF
1604        ) &&
1605
1606        git push void master &&
1607        (
1608                cd void &&
1609                git diff --quiet &&
1610                git diff --cached --quiet &&
1611                test $(git -C .. rev-parse HEAD) = $(git rev-parse HEAD)
1612        )
1613'
1614
1615test_done