t / t5516-fetch-push.shon commit Merge branch 'ld/p4-submit-hint' (5c9c3df)
   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/.pusnInsteadOf" 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 &&
1111                result=$(git rev-parse --verify refs/heads/copy) &&
1112                test "$the_commit" = "$result"
1113        )
1114'
1115
1116test_expect_success 'fetch follows tags by default' '
1117        mk_test testrepo heads/master &&
1118        rm -fr src dst &&
1119        git init src &&
1120        (
1121                cd src &&
1122                git pull ../testrepo master &&
1123                git tag -m "annotated" tag &&
1124                git for-each-ref >tmp1 &&
1125                (
1126                        cat tmp1
1127                        sed -n "s|refs/heads/master$|refs/remotes/origin/master|p" tmp1
1128                ) |
1129                sort -k 3 >../expect
1130        ) &&
1131        git init dst &&
1132        (
1133                cd dst &&
1134                git remote add origin ../src &&
1135                git config branch.master.remote origin &&
1136                git config branch.master.merge refs/heads/master &&
1137                git pull &&
1138                git for-each-ref >../actual
1139        ) &&
1140        test_cmp expect actual
1141'
1142
1143test_expect_success 'pushing a specific ref applies remote.$name.push as refmap' '
1144        mk_test testrepo heads/master &&
1145        rm -fr src dst &&
1146        git init src &&
1147        git init --bare dst &&
1148        (
1149                cd src &&
1150                git pull ../testrepo master &&
1151                git branch next &&
1152                git config remote.dst.url ../dst &&
1153                git config remote.dst.push "+refs/heads/*:refs/remotes/src/*" &&
1154                git push dst master &&
1155                git show-ref refs/heads/master |
1156                sed -e "s|refs/heads/|refs/remotes/src/|" >../dst/expect
1157        ) &&
1158        (
1159                cd dst &&
1160                test_must_fail git show-ref refs/heads/next &&
1161                test_must_fail git show-ref refs/heads/master &&
1162                git show-ref refs/remotes/src/master >actual
1163        ) &&
1164        test_cmp dst/expect dst/actual
1165'
1166
1167test_expect_success 'with no remote.$name.push, it is not used as refmap' '
1168        mk_test testrepo heads/master &&
1169        rm -fr src dst &&
1170        git init src &&
1171        git init --bare dst &&
1172        (
1173                cd src &&
1174                git pull ../testrepo master &&
1175                git branch next &&
1176                git config remote.dst.url ../dst &&
1177                git config push.default matching &&
1178                git push dst master &&
1179                git show-ref refs/heads/master >../dst/expect
1180        ) &&
1181        (
1182                cd dst &&
1183                test_must_fail git show-ref refs/heads/next &&
1184                git show-ref refs/heads/master >actual
1185        ) &&
1186        test_cmp dst/expect dst/actual
1187'
1188
1189test_expect_success 'with no remote.$name.push, upstream mapping is used' '
1190        mk_test testrepo heads/master &&
1191        rm -fr src dst &&
1192        git init src &&
1193        git init --bare dst &&
1194        (
1195                cd src &&
1196                git pull ../testrepo master &&
1197                git branch next &&
1198                git config remote.dst.url ../dst &&
1199                git config remote.dst.fetch "+refs/heads/*:refs/remotes/dst/*" &&
1200                git config push.default upstream &&
1201
1202                git config branch.master.merge refs/heads/trunk &&
1203                git config branch.master.remote dst &&
1204
1205                git push dst master &&
1206                git show-ref refs/heads/master |
1207                sed -e "s|refs/heads/master|refs/heads/trunk|" >../dst/expect
1208        ) &&
1209        (
1210                cd dst &&
1211                test_must_fail git show-ref refs/heads/master &&
1212                test_must_fail git show-ref refs/heads/next &&
1213                git show-ref refs/heads/trunk >actual
1214        ) &&
1215        test_cmp dst/expect dst/actual
1216'
1217
1218test_expect_success 'push does not follow tags by default' '
1219        mk_test testrepo heads/master &&
1220        rm -fr src dst &&
1221        git init src &&
1222        git init --bare dst &&
1223        (
1224                cd src &&
1225                git pull ../testrepo master &&
1226                git tag -m "annotated" tag &&
1227                git checkout -b another &&
1228                git commit --allow-empty -m "future commit" &&
1229                git tag -m "future" future &&
1230                git checkout master &&
1231                git for-each-ref refs/heads/master >../expect &&
1232                git push ../dst master
1233        ) &&
1234        (
1235                cd dst &&
1236                git for-each-ref >../actual
1237        ) &&
1238        test_cmp expect actual
1239'
1240
1241test_expect_success 'push --follow-tag only pushes relevant tags' '
1242        mk_test testrepo heads/master &&
1243        rm -fr src dst &&
1244        git init src &&
1245        git init --bare dst &&
1246        (
1247                cd src &&
1248                git pull ../testrepo master &&
1249                git tag -m "annotated" tag &&
1250                git checkout -b another &&
1251                git commit --allow-empty -m "future commit" &&
1252                git tag -m "future" future &&
1253                git checkout master &&
1254                git for-each-ref refs/heads/master refs/tags/tag >../expect
1255                git push --follow-tag ../dst master
1256        ) &&
1257        (
1258                cd dst &&
1259                git for-each-ref >../actual
1260        ) &&
1261        test_cmp expect actual
1262'
1263
1264test_expect_success 'push --no-thin must produce non-thin pack' '
1265        cat >>path1 <<\EOF &&
1266keep base version of path1 big enough, compared to the new changes
1267later, in order to pass size heuristics in
1268builtin/pack-objects.c:try_delta()
1269EOF
1270        git commit -am initial &&
1271        git init no-thin &&
1272        git --git-dir=no-thin/.git config receive.unpacklimit 0 &&
1273        git push no-thin/.git refs/heads/master:refs/heads/foo &&
1274        echo modified >> path1 &&
1275        git commit -am modified &&
1276        git repack -adf &&
1277        rcvpck="git receive-pack --reject-thin-pack-for-testing" &&
1278        git push --no-thin --receive-pack="$rcvpck" no-thin/.git refs/heads/master:refs/heads/foo
1279'
1280
1281test_expect_success 'pushing a tag pushes the tagged object' '
1282        rm -rf dst.git &&
1283        blob=$(echo unreferenced | git hash-object -w --stdin) &&
1284        git tag -m foo tag-of-blob $blob &&
1285        git init --bare dst.git &&
1286        git push dst.git tag-of-blob &&
1287        # the receiving index-pack should have noticed
1288        # any problems, but we double check
1289        echo unreferenced >expect &&
1290        git --git-dir=dst.git cat-file blob tag-of-blob >actual &&
1291        test_cmp expect actual
1292'
1293
1294test_expect_success 'push into bare respects core.logallrefupdates' '
1295        rm -rf dst.git &&
1296        git init --bare dst.git &&
1297        git -C dst.git config core.logallrefupdates true &&
1298
1299        # double push to test both with and without
1300        # the actual pack transfer
1301        git push dst.git master:one &&
1302        echo "one@{0} push" >expect &&
1303        git -C dst.git log -g --format="%gd %gs" one >actual &&
1304        test_cmp expect actual &&
1305
1306        git push dst.git master:two &&
1307        echo "two@{0} push" >expect &&
1308        git -C dst.git log -g --format="%gd %gs" two >actual &&
1309        test_cmp expect actual
1310'
1311
1312test_expect_success 'fetch into bare respects core.logallrefupdates' '
1313        rm -rf dst.git &&
1314        git init --bare dst.git &&
1315        (
1316                cd dst.git &&
1317                git config core.logallrefupdates true &&
1318
1319                # as above, we double-fetch to test both
1320                # with and without pack transfer
1321                git fetch .. master:one &&
1322                echo "one@{0} fetch .. master:one: storing head" >expect &&
1323                git log -g --format="%gd %gs" one >actual &&
1324                test_cmp expect actual &&
1325
1326                git fetch .. master:two &&
1327                echo "two@{0} fetch .. master:two: storing head" >expect &&
1328                git log -g --format="%gd %gs" two >actual &&
1329                test_cmp expect actual
1330        )
1331'
1332
1333test_expect_success 'receive.denyCurrentBranch = updateInstead' '
1334        git push testrepo master &&
1335        (
1336                cd testrepo &&
1337                git reset --hard &&
1338                git config receive.denyCurrentBranch updateInstead
1339        ) &&
1340        test_commit third path2 &&
1341
1342        # Try pushing into a repository with pristine working tree
1343        git push testrepo master &&
1344        (
1345                cd testrepo &&
1346                git update-index -q --refresh &&
1347                git diff-files --quiet -- &&
1348                git diff-index --quiet --cached HEAD -- &&
1349                test third = "$(cat path2)" &&
1350                test $(git -C .. rev-parse HEAD) = $(git rev-parse HEAD)
1351        ) &&
1352
1353        # Try pushing into a repository with working tree needing a refresh
1354        (
1355                cd testrepo &&
1356                git reset --hard HEAD^ &&
1357                test $(git -C .. rev-parse HEAD^) = $(git rev-parse HEAD) &&
1358                test-chmtime +100 path1
1359        ) &&
1360        git push testrepo master &&
1361        (
1362                cd testrepo &&
1363                git update-index -q --refresh &&
1364                git diff-files --quiet -- &&
1365                git diff-index --quiet --cached HEAD -- &&
1366                test_cmp ../path1 path1 &&
1367                test third = "$(cat path2)" &&
1368                test $(git -C .. rev-parse HEAD) = $(git rev-parse HEAD)
1369        ) &&
1370
1371        # Update what is to be pushed
1372        test_commit fourth path2 &&
1373
1374        # Try pushing into a repository with a dirty working tree
1375        # (1) the working tree updated
1376        (
1377                cd testrepo &&
1378                echo changed >path1
1379        ) &&
1380        test_must_fail git push testrepo master &&
1381        (
1382                cd testrepo &&
1383                test $(git -C .. rev-parse HEAD^) = $(git rev-parse HEAD) &&
1384                git diff --quiet --cached &&
1385                test changed = "$(cat path1)"
1386        ) &&
1387
1388        # (2) the index updated
1389        (
1390                cd testrepo &&
1391                echo changed >path1 &&
1392                git add path1
1393        ) &&
1394        test_must_fail git push testrepo master &&
1395        (
1396                cd testrepo &&
1397                test $(git -C .. rev-parse HEAD^) = $(git rev-parse HEAD) &&
1398                git diff --quiet &&
1399                test changed = "$(cat path1)"
1400        ) &&
1401
1402        # Introduce a new file in the update
1403        test_commit fifth path3 &&
1404
1405        # (3) the working tree has an untracked file that would interfere
1406        (
1407                cd testrepo &&
1408                git reset --hard &&
1409                echo changed >path3
1410        ) &&
1411        test_must_fail git push testrepo master &&
1412        (
1413                cd testrepo &&
1414                test $(git -C .. rev-parse HEAD^^) = $(git rev-parse HEAD) &&
1415                git diff --quiet &&
1416                git diff --quiet --cached &&
1417                test changed = "$(cat path3)"
1418        ) &&
1419
1420        # (4) the target changes to what gets pushed but it still is a change
1421        (
1422                cd testrepo &&
1423                git reset --hard &&
1424                echo fifth >path3 &&
1425                git add path3
1426        ) &&
1427        test_must_fail git push testrepo master &&
1428        (
1429                cd testrepo &&
1430                test $(git -C .. rev-parse HEAD^^) = $(git rev-parse HEAD) &&
1431                git diff --quiet &&
1432                test fifth = "$(cat path3)"
1433        )
1434
1435'
1436
1437test_done