t / t5516-fetch-push.shon commit Merge branch 'jk/daemon-fixes' (1772ad1)
   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        ! 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 2>err &&
1102                test_i18ngrep "Server does not allow request for unadvertised object" err &&
1103                test_must_fail git rev-parse --verify refs/heads/copy &&
1104
1105                # the server side can allow it to succeed
1106                (
1107                        cd ../testrepo &&
1108                        git config uploadpack.allowtipsha1inwant true
1109                ) &&
1110
1111                git fetch -v ../testrepo $the_commit:refs/heads/copy master:refs/heads/extra &&
1112                cat >expect <<-EOF &&
1113                $the_commit
1114                $the_first_commit
1115                EOF
1116                {
1117                        git rev-parse --verify refs/heads/copy &&
1118                        git rev-parse --verify refs/heads/extra
1119                } >actual &&
1120                test_cmp expect actual
1121        )
1122'
1123
1124for configallowtipsha1inwant in true false
1125do
1126        test_expect_success "shallow fetch reachable SHA1 (but not a ref), allowtipsha1inwant=$configallowtipsha1inwant" '
1127                mk_empty testrepo &&
1128                (
1129                        cd testrepo &&
1130                        git config uploadpack.allowtipsha1inwant $configallowtipsha1inwant &&
1131                        git commit --allow-empty -m foo &&
1132                        git commit --allow-empty -m bar
1133                ) &&
1134                SHA1=$(git --git-dir=testrepo/.git rev-parse HEAD^) &&
1135                mk_empty shallow &&
1136                (
1137                        cd shallow &&
1138                        test_must_fail git fetch --depth=1 ../testrepo/.git $SHA1 &&
1139                        git --git-dir=../testrepo/.git config uploadpack.allowreachablesha1inwant true &&
1140                        git fetch --depth=1 ../testrepo/.git $SHA1 &&
1141                        git cat-file commit $SHA1
1142                )
1143        '
1144
1145        test_expect_success "deny fetch unreachable SHA1, allowtipsha1inwant=$configallowtipsha1inwant" '
1146                mk_empty testrepo &&
1147                (
1148                        cd testrepo &&
1149                        git config uploadpack.allowtipsha1inwant $configallowtipsha1inwant &&
1150                        git commit --allow-empty -m foo &&
1151                        git commit --allow-empty -m bar &&
1152                        git commit --allow-empty -m xyz
1153                ) &&
1154                SHA1_1=$(git --git-dir=testrepo/.git rev-parse HEAD^^) &&
1155                SHA1_2=$(git --git-dir=testrepo/.git rev-parse HEAD^) &&
1156                SHA1_3=$(git --git-dir=testrepo/.git rev-parse HEAD) &&
1157                (
1158                        cd testrepo &&
1159                        git reset --hard $SHA1_2 &&
1160                        git cat-file commit $SHA1_1 &&
1161                        git cat-file commit $SHA1_3
1162                ) &&
1163                mk_empty shallow &&
1164                (
1165                        cd shallow &&
1166                        test_must_fail ok=sigpipe git fetch ../testrepo/.git $SHA1_3 &&
1167                        test_must_fail ok=sigpipe git fetch ../testrepo/.git $SHA1_1 &&
1168                        git --git-dir=../testrepo/.git config uploadpack.allowreachablesha1inwant true &&
1169                        git fetch ../testrepo/.git $SHA1_1 &&
1170                        git cat-file commit $SHA1_1 &&
1171                        test_must_fail git cat-file commit $SHA1_2 &&
1172                        git fetch ../testrepo/.git $SHA1_2 &&
1173                        git cat-file commit $SHA1_2 &&
1174                        test_must_fail ok=sigpipe git fetch ../testrepo/.git $SHA1_3
1175                )
1176        '
1177done
1178
1179test_expect_success 'fetch follows tags by default' '
1180        mk_test testrepo heads/master &&
1181        rm -fr src dst &&
1182        git init src &&
1183        (
1184                cd src &&
1185                git pull ../testrepo master &&
1186                git tag -m "annotated" tag &&
1187                git for-each-ref >tmp1 &&
1188                (
1189                        cat tmp1
1190                        sed -n "s|refs/heads/master$|refs/remotes/origin/master|p" tmp1
1191                ) |
1192                sort -k 3 >../expect
1193        ) &&
1194        git init dst &&
1195        (
1196                cd dst &&
1197                git remote add origin ../src &&
1198                git config branch.master.remote origin &&
1199                git config branch.master.merge refs/heads/master &&
1200                git pull &&
1201                git for-each-ref >../actual
1202        ) &&
1203        test_cmp expect actual
1204'
1205
1206test_expect_success 'pushing a specific ref applies remote.$name.push as refmap' '
1207        mk_test testrepo heads/master &&
1208        rm -fr src dst &&
1209        git init src &&
1210        git init --bare dst &&
1211        (
1212                cd src &&
1213                git pull ../testrepo master &&
1214                git branch next &&
1215                git config remote.dst.url ../dst &&
1216                git config remote.dst.push "+refs/heads/*:refs/remotes/src/*" &&
1217                git push dst master &&
1218                git show-ref refs/heads/master |
1219                sed -e "s|refs/heads/|refs/remotes/src/|" >../dst/expect
1220        ) &&
1221        (
1222                cd dst &&
1223                test_must_fail git show-ref refs/heads/next &&
1224                test_must_fail git show-ref refs/heads/master &&
1225                git show-ref refs/remotes/src/master >actual
1226        ) &&
1227        test_cmp dst/expect dst/actual
1228'
1229
1230test_expect_success 'with no remote.$name.push, it is not used as refmap' '
1231        mk_test testrepo heads/master &&
1232        rm -fr src dst &&
1233        git init src &&
1234        git init --bare dst &&
1235        (
1236                cd src &&
1237                git pull ../testrepo master &&
1238                git branch next &&
1239                git config remote.dst.url ../dst &&
1240                git config push.default matching &&
1241                git push dst master &&
1242                git show-ref refs/heads/master >../dst/expect
1243        ) &&
1244        (
1245                cd dst &&
1246                test_must_fail git show-ref refs/heads/next &&
1247                git show-ref refs/heads/master >actual
1248        ) &&
1249        test_cmp dst/expect dst/actual
1250'
1251
1252test_expect_success 'with no remote.$name.push, upstream mapping is used' '
1253        mk_test testrepo heads/master &&
1254        rm -fr src dst &&
1255        git init src &&
1256        git init --bare dst &&
1257        (
1258                cd src &&
1259                git pull ../testrepo master &&
1260                git branch next &&
1261                git config remote.dst.url ../dst &&
1262                git config remote.dst.fetch "+refs/heads/*:refs/remotes/dst/*" &&
1263                git config push.default upstream &&
1264
1265                git config branch.master.merge refs/heads/trunk &&
1266                git config branch.master.remote dst &&
1267
1268                git push dst master &&
1269                git show-ref refs/heads/master |
1270                sed -e "s|refs/heads/master|refs/heads/trunk|" >../dst/expect
1271        ) &&
1272        (
1273                cd dst &&
1274                test_must_fail git show-ref refs/heads/master &&
1275                test_must_fail git show-ref refs/heads/next &&
1276                git show-ref refs/heads/trunk >actual
1277        ) &&
1278        test_cmp dst/expect dst/actual
1279'
1280
1281test_expect_success 'push does not follow tags by default' '
1282        mk_test testrepo heads/master &&
1283        rm -fr src dst &&
1284        git init src &&
1285        git init --bare dst &&
1286        (
1287                cd src &&
1288                git pull ../testrepo master &&
1289                git tag -m "annotated" tag &&
1290                git checkout -b another &&
1291                git commit --allow-empty -m "future commit" &&
1292                git tag -m "future" future &&
1293                git checkout master &&
1294                git for-each-ref refs/heads/master >../expect &&
1295                git push ../dst master
1296        ) &&
1297        (
1298                cd dst &&
1299                git for-each-ref >../actual
1300        ) &&
1301        test_cmp expect actual
1302'
1303
1304test_expect_success 'push --follow-tag only pushes relevant tags' '
1305        mk_test testrepo heads/master &&
1306        rm -fr src dst &&
1307        git init src &&
1308        git init --bare dst &&
1309        (
1310                cd src &&
1311                git pull ../testrepo master &&
1312                git tag -m "annotated" tag &&
1313                git checkout -b another &&
1314                git commit --allow-empty -m "future commit" &&
1315                git tag -m "future" future &&
1316                git checkout master &&
1317                git for-each-ref refs/heads/master refs/tags/tag >../expect
1318                git push --follow-tag ../dst master
1319        ) &&
1320        (
1321                cd dst &&
1322                git for-each-ref >../actual
1323        ) &&
1324        test_cmp expect actual
1325'
1326
1327test_expect_success 'push --no-thin must produce non-thin pack' '
1328        cat >>path1 <<\EOF &&
1329keep base version of path1 big enough, compared to the new changes
1330later, in order to pass size heuristics in
1331builtin/pack-objects.c:try_delta()
1332EOF
1333        git commit -am initial &&
1334        git init no-thin &&
1335        git --git-dir=no-thin/.git config receive.unpacklimit 0 &&
1336        git push no-thin/.git refs/heads/master:refs/heads/foo &&
1337        echo modified >> path1 &&
1338        git commit -am modified &&
1339        git repack -adf &&
1340        rcvpck="git receive-pack --reject-thin-pack-for-testing" &&
1341        git push --no-thin --receive-pack="$rcvpck" no-thin/.git refs/heads/master:refs/heads/foo
1342'
1343
1344test_expect_success 'pushing a tag pushes the tagged object' '
1345        rm -rf dst.git &&
1346        blob=$(echo unreferenced | git hash-object -w --stdin) &&
1347        git tag -m foo tag-of-blob $blob &&
1348        git init --bare dst.git &&
1349        git push dst.git tag-of-blob &&
1350        # the receiving index-pack should have noticed
1351        # any problems, but we double check
1352        echo unreferenced >expect &&
1353        git --git-dir=dst.git cat-file blob tag-of-blob >actual &&
1354        test_cmp expect actual
1355'
1356
1357test_expect_success 'push into bare respects core.logallrefupdates' '
1358        rm -rf dst.git &&
1359        git init --bare dst.git &&
1360        git -C dst.git config core.logallrefupdates true &&
1361
1362        # double push to test both with and without
1363        # the actual pack transfer
1364        git push dst.git master:one &&
1365        echo "one@{0} push" >expect &&
1366        git -C dst.git log -g --format="%gd %gs" one >actual &&
1367        test_cmp expect actual &&
1368
1369        git push dst.git master:two &&
1370        echo "two@{0} push" >expect &&
1371        git -C dst.git log -g --format="%gd %gs" two >actual &&
1372        test_cmp expect actual
1373'
1374
1375test_expect_success 'fetch into bare respects core.logallrefupdates' '
1376        rm -rf dst.git &&
1377        git init --bare dst.git &&
1378        (
1379                cd dst.git &&
1380                git config core.logallrefupdates true &&
1381
1382                # as above, we double-fetch to test both
1383                # with and without pack transfer
1384                git fetch .. master:one &&
1385                echo "one@{0} fetch .. master:one: storing head" >expect &&
1386                git log -g --format="%gd %gs" one >actual &&
1387                test_cmp expect actual &&
1388
1389                git fetch .. master:two &&
1390                echo "two@{0} fetch .. master:two: storing head" >expect &&
1391                git log -g --format="%gd %gs" two >actual &&
1392                test_cmp expect actual
1393        )
1394'
1395
1396test_expect_success 'receive.denyCurrentBranch = updateInstead' '
1397        git push testrepo master &&
1398        (
1399                cd testrepo &&
1400                git reset --hard &&
1401                git config receive.denyCurrentBranch updateInstead
1402        ) &&
1403        test_commit third path2 &&
1404
1405        # Try pushing into a repository with pristine working tree
1406        git push testrepo master &&
1407        (
1408                cd testrepo &&
1409                git update-index -q --refresh &&
1410                git diff-files --quiet -- &&
1411                git diff-index --quiet --cached HEAD -- &&
1412                test third = "$(cat path2)" &&
1413                test $(git -C .. rev-parse HEAD) = $(git rev-parse HEAD)
1414        ) &&
1415
1416        # Try pushing into a repository with working tree needing a refresh
1417        (
1418                cd testrepo &&
1419                git reset --hard HEAD^ &&
1420                test $(git -C .. rev-parse HEAD^) = $(git rev-parse HEAD) &&
1421                test-chmtime +100 path1
1422        ) &&
1423        git push testrepo master &&
1424        (
1425                cd testrepo &&
1426                git update-index -q --refresh &&
1427                git diff-files --quiet -- &&
1428                git diff-index --quiet --cached HEAD -- &&
1429                test_cmp ../path1 path1 &&
1430                test third = "$(cat path2)" &&
1431                test $(git -C .. rev-parse HEAD) = $(git rev-parse HEAD)
1432        ) &&
1433
1434        # Update what is to be pushed
1435        test_commit fourth path2 &&
1436
1437        # Try pushing into a repository with a dirty working tree
1438        # (1) the working tree updated
1439        (
1440                cd testrepo &&
1441                echo changed >path1
1442        ) &&
1443        test_must_fail git push testrepo master &&
1444        (
1445                cd testrepo &&
1446                test $(git -C .. rev-parse HEAD^) = $(git rev-parse HEAD) &&
1447                git diff --quiet --cached &&
1448                test changed = "$(cat path1)"
1449        ) &&
1450
1451        # (2) the index updated
1452        (
1453                cd testrepo &&
1454                echo changed >path1 &&
1455                git add path1
1456        ) &&
1457        test_must_fail git push testrepo master &&
1458        (
1459                cd testrepo &&
1460                test $(git -C .. rev-parse HEAD^) = $(git rev-parse HEAD) &&
1461                git diff --quiet &&
1462                test changed = "$(cat path1)"
1463        ) &&
1464
1465        # Introduce a new file in the update
1466        test_commit fifth path3 &&
1467
1468        # (3) the working tree has an untracked file that would interfere
1469        (
1470                cd testrepo &&
1471                git reset --hard &&
1472                echo changed >path3
1473        ) &&
1474        test_must_fail git push testrepo master &&
1475        (
1476                cd testrepo &&
1477                test $(git -C .. rev-parse HEAD^^) = $(git rev-parse HEAD) &&
1478                git diff --quiet &&
1479                git diff --quiet --cached &&
1480                test changed = "$(cat path3)"
1481        ) &&
1482
1483        # (4) the target changes to what gets pushed but it still is a change
1484        (
1485                cd testrepo &&
1486                git reset --hard &&
1487                echo fifth >path3 &&
1488                git add path3
1489        ) &&
1490        test_must_fail git push testrepo master &&
1491        (
1492                cd testrepo &&
1493                test $(git -C .. rev-parse HEAD^^) = $(git rev-parse HEAD) &&
1494                git diff --quiet &&
1495                test fifth = "$(cat path3)"
1496        ) &&
1497
1498        # (5) push into void
1499        rm -fr void &&
1500        git init void &&
1501        (
1502                cd void &&
1503                git config receive.denyCurrentBranch updateInstead
1504        ) &&
1505        git push void master &&
1506        (
1507                cd void &&
1508                test $(git -C .. rev-parse master) = $(git rev-parse HEAD) &&
1509                git diff --quiet &&
1510                git diff --cached --quiet
1511        )
1512'
1513
1514test_expect_success 'updateInstead with push-to-checkout hook' '
1515        rm -fr testrepo &&
1516        git init testrepo &&
1517        (
1518                cd testrepo &&
1519                git pull .. master &&
1520                git reset --hard HEAD^^ &&
1521                git tag initial &&
1522                git config receive.denyCurrentBranch updateInstead &&
1523                write_script .git/hooks/push-to-checkout <<-\EOF
1524                echo >&2 updating from $(git rev-parse HEAD)
1525                echo >&2 updating to "$1"
1526
1527                git update-index -q --refresh &&
1528                git read-tree -u -m HEAD "$1" || {
1529                        status=$?
1530                        echo >&2 read-tree failed
1531                        exit $status
1532                }
1533                EOF
1534        ) &&
1535
1536        # Try pushing into a pristine
1537        git push testrepo master &&
1538        (
1539                cd testrepo &&
1540                git diff --quiet &&
1541                git diff HEAD --quiet &&
1542                test $(git -C .. rev-parse HEAD) = $(git rev-parse HEAD)
1543        ) &&
1544
1545        # Try pushing into a repository with conflicting change
1546        (
1547                cd testrepo &&
1548                git reset --hard initial &&
1549                echo conflicting >path2
1550        ) &&
1551        test_must_fail git push testrepo master &&
1552        (
1553                cd testrepo &&
1554                test $(git rev-parse initial) = $(git rev-parse HEAD) &&
1555                test conflicting = "$(cat path2)" &&
1556                git diff-index --quiet --cached HEAD
1557        ) &&
1558
1559        # Try pushing into a repository with unrelated change
1560        (
1561                cd testrepo &&
1562                git reset --hard initial &&
1563                echo unrelated >path1 &&
1564                echo irrelevant >path5 &&
1565                git add path5
1566        ) &&
1567        git push testrepo master &&
1568        (
1569                cd testrepo &&
1570                test "$(cat path1)" = unrelated &&
1571                test "$(cat path5)" = irrelevant &&
1572                test "$(git diff --name-only --cached HEAD)" = path5 &&
1573                test $(git -C .. rev-parse HEAD) = $(git rev-parse HEAD)
1574        ) &&
1575
1576        # push into void
1577        rm -fr void &&
1578        git init void &&
1579        (
1580                cd void &&
1581                git config receive.denyCurrentBranch updateInstead &&
1582                write_script .git/hooks/push-to-checkout <<-\EOF
1583                if git rev-parse --quiet --verify HEAD
1584                then
1585                        has_head=yes
1586                        echo >&2 updating from $(git rev-parse HEAD)
1587                else
1588                        has_head=no
1589                        echo >&2 pushing into void
1590                fi
1591                echo >&2 updating to "$1"
1592
1593                git update-index -q --refresh &&
1594                case "$has_head" in
1595                yes)
1596                        git read-tree -u -m HEAD "$1" ;;
1597                no)
1598                        git read-tree -u -m "$1" ;;
1599                esac || {
1600                        status=$?
1601                        echo >&2 read-tree failed
1602                        exit $status
1603                }
1604                EOF
1605        ) &&
1606
1607        git push void master &&
1608        (
1609                cd void &&
1610                git diff --quiet &&
1611                git diff --cached --quiet &&
1612                test $(git -C .. rev-parse HEAD) = $(git rev-parse HEAD)
1613        )
1614'
1615
1616test_done