t / t5516-fetch-push.shon commit check_aliased_update: strcpy() instead of strcat() to copy (0e71bc3)
   1#!/bin/sh
   2
   3test_description='fetching and pushing, with or without wildcard'
   4
   5. ./test-lib.sh
   6
   7D=`pwd`
   8
   9mk_empty () {
  10        rm -fr testrepo &&
  11        mkdir testrepo &&
  12        (
  13                cd testrepo &&
  14                git init &&
  15                git config receive.denyCurrentBranch warn &&
  16                mv .git/hooks .git/hooks-disabled
  17        )
  18}
  19
  20mk_test () {
  21        mk_empty &&
  22        (
  23                for ref in "$@"
  24                do
  25                        git push testrepo $the_first_commit:refs/$ref || {
  26                                echo "Oops, push refs/$ref failure"
  27                                exit 1
  28                        }
  29                done &&
  30                cd testrepo &&
  31                for ref in "$@"
  32                do
  33                        r=$(git show-ref -s --verify refs/$ref) &&
  34                        test "z$r" = "z$the_first_commit" || {
  35                                echo "Oops, refs/$ref is wrong"
  36                                exit 1
  37                        }
  38                done &&
  39                git fsck --full
  40        )
  41}
  42
  43mk_child() {
  44        rm -rf "$1" &&
  45        git clone testrepo "$1"
  46}
  47
  48check_push_result () {
  49        (
  50                cd testrepo &&
  51                it="$1" &&
  52                shift
  53                for ref in "$@"
  54                do
  55                        r=$(git show-ref -s --verify refs/$ref) &&
  56                        test "z$r" = "z$it" || {
  57                                echo "Oops, refs/$ref is wrong"
  58                                exit 1
  59                        }
  60                done &&
  61                git fsck --full
  62        )
  63}
  64
  65test_expect_success setup '
  66
  67        : >path1 &&
  68        git add path1 &&
  69        test_tick &&
  70        git commit -a -m repo &&
  71        the_first_commit=$(git show-ref -s --verify refs/heads/master) &&
  72
  73        : >path2 &&
  74        git add path2 &&
  75        test_tick &&
  76        git commit -a -m second &&
  77        the_commit=$(git show-ref -s --verify refs/heads/master)
  78
  79'
  80
  81test_expect_success 'fetch without wildcard' '
  82        mk_empty &&
  83        (
  84                cd testrepo &&
  85                git fetch .. refs/heads/master:refs/remotes/origin/master &&
  86
  87                r=$(git show-ref -s --verify refs/remotes/origin/master) &&
  88                test "z$r" = "z$the_commit" &&
  89
  90                test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
  91        )
  92'
  93
  94test_expect_success 'fetch with wildcard' '
  95        mk_empty &&
  96        (
  97                cd testrepo &&
  98                git config remote.up.url .. &&
  99                git config remote.up.fetch "refs/heads/*:refs/remotes/origin/*" &&
 100                git fetch up &&
 101
 102                r=$(git show-ref -s --verify refs/remotes/origin/master) &&
 103                test "z$r" = "z$the_commit" &&
 104
 105                test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
 106        )
 107'
 108
 109test_expect_success 'fetch with insteadOf' '
 110        mk_empty &&
 111        (
 112                TRASH=$(pwd)/ &&
 113                cd testrepo &&
 114                git config "url.$TRASH.insteadOf" trash/ &&
 115                git config remote.up.url trash/. &&
 116                git config remote.up.fetch "refs/heads/*:refs/remotes/origin/*" &&
 117                git fetch up &&
 118
 119                r=$(git show-ref -s --verify refs/remotes/origin/master) &&
 120                test "z$r" = "z$the_commit" &&
 121
 122                test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
 123        )
 124'
 125
 126test_expect_success 'fetch with pushInsteadOf (should not rewrite)' '
 127        mk_empty &&
 128        (
 129                TRASH=$(pwd)/ &&
 130                cd testrepo &&
 131                git config "url.trash/.pushInsteadOf" "$TRASH" &&
 132                git config remote.up.url "$TRASH." &&
 133                git config remote.up.fetch "refs/heads/*:refs/remotes/origin/*" &&
 134                git fetch up &&
 135
 136                r=$(git show-ref -s --verify refs/remotes/origin/master) &&
 137                test "z$r" = "z$the_commit" &&
 138
 139                test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
 140        )
 141'
 142
 143test_expect_success 'push without wildcard' '
 144        mk_empty &&
 145
 146        git push testrepo refs/heads/master:refs/remotes/origin/master &&
 147        (
 148                cd testrepo &&
 149                r=$(git show-ref -s --verify refs/remotes/origin/master) &&
 150                test "z$r" = "z$the_commit" &&
 151
 152                test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
 153        )
 154'
 155
 156test_expect_success 'push with wildcard' '
 157        mk_empty &&
 158
 159        git push testrepo "refs/heads/*:refs/remotes/origin/*" &&
 160        (
 161                cd testrepo &&
 162                r=$(git show-ref -s --verify refs/remotes/origin/master) &&
 163                test "z$r" = "z$the_commit" &&
 164
 165                test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
 166        )
 167'
 168
 169test_expect_success 'push with insteadOf' '
 170        mk_empty &&
 171        TRASH="$(pwd)/" &&
 172        git config "url.$TRASH.insteadOf" trash/ &&
 173        git push trash/testrepo refs/heads/master:refs/remotes/origin/master &&
 174        (
 175                cd testrepo &&
 176                r=$(git show-ref -s --verify refs/remotes/origin/master) &&
 177                test "z$r" = "z$the_commit" &&
 178
 179                test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
 180        )
 181'
 182
 183test_expect_success 'push with pushInsteadOf' '
 184        mk_empty &&
 185        TRASH="$(pwd)/" &&
 186        git config "url.$TRASH.pushInsteadOf" trash/ &&
 187        git push trash/testrepo refs/heads/master:refs/remotes/origin/master &&
 188        (
 189                cd testrepo &&
 190                r=$(git show-ref -s --verify refs/remotes/origin/master) &&
 191                test "z$r" = "z$the_commit" &&
 192
 193                test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
 194        )
 195'
 196
 197test_expect_success 'push with pushInsteadOf and explicit pushurl (pushInsteadOf should not rewrite)' '
 198        mk_empty &&
 199        TRASH="$(pwd)/" &&
 200        git config "url.trash2/.pushInsteadOf" trash/ &&
 201        git config remote.r.url trash/wrong &&
 202        git config remote.r.pushurl "$TRASH/testrepo" &&
 203        git push r refs/heads/master:refs/remotes/origin/master &&
 204        (
 205                cd testrepo &&
 206                r=$(git show-ref -s --verify refs/remotes/origin/master) &&
 207                test "z$r" = "z$the_commit" &&
 208
 209                test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
 210        )
 211'
 212
 213test_expect_success 'push with matching heads' '
 214
 215        mk_test heads/master &&
 216        git push testrepo &&
 217        check_push_result $the_commit heads/master
 218
 219'
 220
 221test_expect_success 'push with matching heads on the command line' '
 222
 223        mk_test heads/master &&
 224        git push testrepo : &&
 225        check_push_result $the_commit heads/master
 226
 227'
 228
 229test_expect_success 'failed (non-fast-forward) push with matching heads' '
 230
 231        mk_test heads/master &&
 232        git push testrepo : &&
 233        git commit --amend -massaged &&
 234        test_must_fail git push testrepo &&
 235        check_push_result $the_commit heads/master &&
 236        git reset --hard $the_commit
 237
 238'
 239
 240test_expect_success 'push --force with matching heads' '
 241
 242        mk_test heads/master &&
 243        git push testrepo : &&
 244        git commit --amend -massaged &&
 245        git push --force testrepo &&
 246        ! check_push_result $the_commit heads/master &&
 247        git reset --hard $the_commit
 248
 249'
 250
 251test_expect_success 'push with matching heads and forced update' '
 252
 253        mk_test heads/master &&
 254        git push testrepo : &&
 255        git commit --amend -massaged &&
 256        git push testrepo +: &&
 257        ! check_push_result $the_commit heads/master &&
 258        git reset --hard $the_commit
 259
 260'
 261
 262test_expect_success 'push with no ambiguity (1)' '
 263
 264        mk_test heads/master &&
 265        git push testrepo master:master &&
 266        check_push_result $the_commit heads/master
 267
 268'
 269
 270test_expect_success 'push with no ambiguity (2)' '
 271
 272        mk_test remotes/origin/master &&
 273        git push testrepo master:origin/master &&
 274        check_push_result $the_commit remotes/origin/master
 275
 276'
 277
 278test_expect_success 'push with colon-less refspec, no ambiguity' '
 279
 280        mk_test heads/master heads/t/master &&
 281        git branch -f t/master master &&
 282        git push testrepo master &&
 283        check_push_result $the_commit heads/master &&
 284        check_push_result $the_first_commit heads/t/master
 285
 286'
 287
 288test_expect_success 'push with weak ambiguity (1)' '
 289
 290        mk_test heads/master remotes/origin/master &&
 291        git push testrepo master:master &&
 292        check_push_result $the_commit heads/master &&
 293        check_push_result $the_first_commit remotes/origin/master
 294
 295'
 296
 297test_expect_success 'push with weak ambiguity (2)' '
 298
 299        mk_test heads/master remotes/origin/master remotes/another/master &&
 300        git push testrepo master:master &&
 301        check_push_result $the_commit heads/master &&
 302        check_push_result $the_first_commit remotes/origin/master remotes/another/master
 303
 304'
 305
 306test_expect_success 'push with ambiguity' '
 307
 308        mk_test heads/frotz tags/frotz &&
 309        if git push testrepo master:frotz
 310        then
 311                echo "Oops, should have failed"
 312                false
 313        else
 314                check_push_result $the_first_commit heads/frotz tags/frotz
 315        fi
 316
 317'
 318
 319test_expect_success 'push with colon-less refspec (1)' '
 320
 321        mk_test heads/frotz tags/frotz &&
 322        git branch -f frotz master &&
 323        git push testrepo frotz &&
 324        check_push_result $the_commit heads/frotz &&
 325        check_push_result $the_first_commit tags/frotz
 326
 327'
 328
 329test_expect_success 'push with colon-less refspec (2)' '
 330
 331        mk_test heads/frotz tags/frotz &&
 332        if git show-ref --verify -q refs/heads/frotz
 333        then
 334                git branch -D frotz
 335        fi &&
 336        git tag -f frotz &&
 337        git push testrepo frotz &&
 338        check_push_result $the_commit tags/frotz &&
 339        check_push_result $the_first_commit heads/frotz
 340
 341'
 342
 343test_expect_success 'push with colon-less refspec (3)' '
 344
 345        mk_test &&
 346        if git show-ref --verify -q refs/tags/frotz
 347        then
 348                git tag -d frotz
 349        fi &&
 350        git branch -f frotz master &&
 351        git push testrepo frotz &&
 352        check_push_result $the_commit heads/frotz &&
 353        test 1 = $( cd testrepo && git show-ref | wc -l )
 354'
 355
 356test_expect_success 'push with colon-less refspec (4)' '
 357
 358        mk_test &&
 359        if git show-ref --verify -q refs/heads/frotz
 360        then
 361                git branch -D frotz
 362        fi &&
 363        git tag -f frotz &&
 364        git push testrepo frotz &&
 365        check_push_result $the_commit tags/frotz &&
 366        test 1 = $( cd testrepo && git show-ref | wc -l )
 367
 368'
 369
 370test_expect_success 'push head with non-existant, incomplete dest' '
 371
 372        mk_test &&
 373        git push testrepo master:branch &&
 374        check_push_result $the_commit heads/branch
 375
 376'
 377
 378test_expect_success 'push tag with non-existant, incomplete dest' '
 379
 380        mk_test &&
 381        git tag -f v1.0 &&
 382        git push testrepo v1.0:tag &&
 383        check_push_result $the_commit tags/tag
 384
 385'
 386
 387test_expect_success 'push sha1 with non-existant, incomplete dest' '
 388
 389        mk_test &&
 390        test_must_fail git push testrepo `git rev-parse master`:foo
 391
 392'
 393
 394test_expect_success 'push ref expression with non-existant, incomplete dest' '
 395
 396        mk_test &&
 397        test_must_fail git push testrepo master^:branch
 398
 399'
 400
 401test_expect_success 'push with HEAD' '
 402
 403        mk_test heads/master &&
 404        git checkout master &&
 405        git push testrepo HEAD &&
 406        check_push_result $the_commit heads/master
 407
 408'
 409
 410test_expect_success 'push with HEAD nonexisting at remote' '
 411
 412        mk_test heads/master &&
 413        git checkout -b local master &&
 414        git push testrepo HEAD &&
 415        check_push_result $the_commit heads/local
 416'
 417
 418test_expect_success 'push with +HEAD' '
 419
 420        mk_test heads/master &&
 421        git checkout master &&
 422        git branch -D local &&
 423        git checkout -b local &&
 424        git push testrepo master local &&
 425        check_push_result $the_commit heads/master &&
 426        check_push_result $the_commit heads/local &&
 427
 428        # Without force rewinding should fail
 429        git reset --hard HEAD^ &&
 430        test_must_fail git push testrepo HEAD &&
 431        check_push_result $the_commit heads/local &&
 432
 433        # With force rewinding should succeed
 434        git push testrepo +HEAD &&
 435        check_push_result $the_first_commit heads/local
 436
 437'
 438
 439test_expect_success 'push HEAD with non-existant, incomplete dest' '
 440
 441        mk_test &&
 442        git checkout master &&
 443        git push testrepo HEAD:branch &&
 444        check_push_result $the_commit heads/branch
 445
 446'
 447
 448test_expect_success 'push with config remote.*.push = HEAD' '
 449
 450        mk_test heads/local &&
 451        git checkout master &&
 452        git branch -f local $the_commit &&
 453        (
 454                cd testrepo &&
 455                git checkout local &&
 456                git reset --hard $the_first_commit
 457        ) &&
 458        git config remote.there.url testrepo &&
 459        git config remote.there.push HEAD &&
 460        git config branch.master.remote there &&
 461        git push &&
 462        check_push_result $the_commit heads/master &&
 463        check_push_result $the_first_commit heads/local
 464'
 465
 466# clean up the cruft left with the previous one
 467git config --remove-section remote.there
 468git config --remove-section branch.master
 469
 470test_expect_success 'push with config remote.*.pushurl' '
 471
 472        mk_test heads/master &&
 473        git checkout master &&
 474        git config remote.there.url test2repo &&
 475        git config remote.there.pushurl testrepo &&
 476        git push there &&
 477        check_push_result $the_commit heads/master
 478'
 479
 480# clean up the cruft left with the previous one
 481git config --remove-section remote.there
 482
 483test_expect_success 'push with dry-run' '
 484
 485        mk_test heads/master &&
 486        (cd testrepo &&
 487         old_commit=$(git show-ref -s --verify refs/heads/master)) &&
 488        git push --dry-run testrepo &&
 489        check_push_result $old_commit heads/master
 490'
 491
 492test_expect_success 'push updates local refs' '
 493
 494        mk_test heads/master &&
 495        mk_child child &&
 496        (cd child &&
 497                git pull .. master &&
 498                git push &&
 499        test $(git rev-parse master) = $(git rev-parse remotes/origin/master))
 500
 501'
 502
 503test_expect_success 'push updates up-to-date local refs' '
 504
 505        mk_test heads/master &&
 506        mk_child child1 &&
 507        mk_child child2 &&
 508        (cd child1 && git pull .. master && git push) &&
 509        (cd child2 &&
 510                git pull ../child1 master &&
 511                git push &&
 512        test $(git rev-parse master) = $(git rev-parse remotes/origin/master))
 513
 514'
 515
 516test_expect_success 'push preserves up-to-date packed refs' '
 517
 518        mk_test heads/master &&
 519        mk_child child &&
 520        (cd child &&
 521                git push &&
 522        ! test -f .git/refs/remotes/origin/master)
 523
 524'
 525
 526test_expect_success 'push does not update local refs on failure' '
 527
 528        mk_test heads/master &&
 529        mk_child child &&
 530        mkdir testrepo/.git/hooks &&
 531        echo exit 1 >testrepo/.git/hooks/pre-receive &&
 532        chmod +x testrepo/.git/hooks/pre-receive &&
 533        (cd child &&
 534                git pull .. master
 535                test_must_fail git push &&
 536                test $(git rev-parse master) != \
 537                        $(git rev-parse remotes/origin/master))
 538
 539'
 540
 541test_expect_success 'allow deleting an invalid remote ref' '
 542
 543        mk_test heads/master &&
 544        rm -f testrepo/.git/objects/??/* &&
 545        git push testrepo :refs/heads/master &&
 546        (cd testrepo && test_must_fail git rev-parse --verify refs/heads/master)
 547
 548'
 549
 550test_expect_success 'allow deleting a ref using --delete' '
 551        mk_test heads/master &&
 552        (cd testrepo && git config receive.denyDeleteCurrent warn) &&
 553        git push testrepo --delete master &&
 554        (cd testrepo && test_must_fail git rev-parse --verify refs/heads/master)
 555'
 556
 557test_expect_success 'allow deleting a tag using --delete' '
 558        mk_test heads/master &&
 559        git tag -a -m dummy_message deltag heads/master &&
 560        git push testrepo --tags &&
 561        (cd testrepo && git rev-parse --verify -q refs/tags/deltag) &&
 562        git push testrepo --delete tag deltag &&
 563        (cd testrepo && test_must_fail git rev-parse --verify refs/tags/deltag)
 564'
 565
 566test_expect_success 'push --delete without args aborts' '
 567        mk_test heads/master &&
 568        test_must_fail git push testrepo --delete
 569'
 570
 571test_expect_success 'push --delete refuses src:dest refspecs' '
 572        mk_test heads/master &&
 573        test_must_fail git push testrepo --delete master:foo
 574'
 575
 576test_expect_success 'warn on push to HEAD of non-bare repository' '
 577        mk_test heads/master
 578        (cd testrepo &&
 579                git checkout master &&
 580                git config receive.denyCurrentBranch warn) &&
 581        git push testrepo master 2>stderr &&
 582        grep "warning: updating the current branch" stderr
 583'
 584
 585test_expect_success 'deny push to HEAD of non-bare repository' '
 586        mk_test heads/master
 587        (cd testrepo &&
 588                git checkout master &&
 589                git config receive.denyCurrentBranch true) &&
 590        test_must_fail git push testrepo master
 591'
 592
 593test_expect_success 'allow push to HEAD of bare repository (bare)' '
 594        mk_test heads/master
 595        (cd testrepo &&
 596                git checkout master &&
 597                git config receive.denyCurrentBranch true &&
 598                git config core.bare true) &&
 599        git push testrepo master 2>stderr &&
 600        ! grep "warning: updating the current branch" stderr
 601'
 602
 603test_expect_success 'allow push to HEAD of non-bare repository (config)' '
 604        mk_test heads/master
 605        (cd testrepo &&
 606                git checkout master &&
 607                git config receive.denyCurrentBranch false
 608        ) &&
 609        git push testrepo master 2>stderr &&
 610        ! grep "warning: updating the current branch" stderr
 611'
 612
 613test_expect_success 'fetch with branches' '
 614        mk_empty &&
 615        git branch second $the_first_commit &&
 616        git checkout second &&
 617        echo ".." > testrepo/.git/branches/branch1 &&
 618        (cd testrepo &&
 619                git fetch branch1 &&
 620                r=$(git show-ref -s --verify refs/heads/branch1) &&
 621                test "z$r" = "z$the_commit" &&
 622                test 1 = $(git for-each-ref refs/heads | wc -l)
 623        ) &&
 624        git checkout master
 625'
 626
 627test_expect_success 'fetch with branches containing #' '
 628        mk_empty &&
 629        echo "..#second" > testrepo/.git/branches/branch2 &&
 630        (cd testrepo &&
 631                git fetch branch2 &&
 632                r=$(git show-ref -s --verify refs/heads/branch2) &&
 633                test "z$r" = "z$the_first_commit" &&
 634                test 1 = $(git for-each-ref refs/heads | wc -l)
 635        ) &&
 636        git checkout master
 637'
 638
 639test_expect_success 'push with branches' '
 640        mk_empty &&
 641        git checkout second &&
 642        echo "testrepo" > .git/branches/branch1 &&
 643        git push branch1 &&
 644        (cd testrepo &&
 645                r=$(git show-ref -s --verify refs/heads/master) &&
 646                test "z$r" = "z$the_first_commit" &&
 647                test 1 = $(git for-each-ref refs/heads | wc -l)
 648        )
 649'
 650
 651test_expect_success 'push with branches containing #' '
 652        mk_empty &&
 653        echo "testrepo#branch3" > .git/branches/branch2 &&
 654        git push branch2 &&
 655        (cd testrepo &&
 656                r=$(git show-ref -s --verify refs/heads/branch3) &&
 657                test "z$r" = "z$the_first_commit" &&
 658                test 1 = $(git for-each-ref refs/heads | wc -l)
 659        ) &&
 660        git checkout master
 661'
 662
 663test_expect_success 'push into aliased refs (consistent)' '
 664        mk_test heads/master &&
 665        mk_child child1 &&
 666        mk_child child2 &&
 667        (
 668                cd child1 &&
 669                git branch foo &&
 670                git symbolic-ref refs/heads/bar refs/heads/foo
 671                git config receive.denyCurrentBranch false
 672        ) &&
 673        (
 674                cd child2 &&
 675                >path2 &&
 676                git add path2 &&
 677                test_tick &&
 678                git commit -a -m child2 &&
 679                git branch foo &&
 680                git branch bar &&
 681                git push ../child1 foo bar
 682        )
 683'
 684
 685test_expect_success 'push into aliased refs (inconsistent)' '
 686        mk_test heads/master &&
 687        mk_child child1 &&
 688        mk_child child2 &&
 689        (
 690                cd child1 &&
 691                git branch foo &&
 692                git symbolic-ref refs/heads/bar refs/heads/foo
 693                git config receive.denyCurrentBranch false
 694        ) &&
 695        (
 696                cd child2 &&
 697                >path2 &&
 698                git add path2 &&
 699                test_tick &&
 700                git commit -a -m child2 &&
 701                git branch foo &&
 702                >path3 &&
 703                git add path3 &&
 704                test_tick &&
 705                git commit -a -m child2 &&
 706                git branch bar &&
 707                test_must_fail git push ../child1 foo bar 2>stderr &&
 708                grep "refusing inconsistent update" stderr
 709        )
 710'
 711
 712test_done