230c0cd784b317856749609cf64a5067e35a6965
   1#!/bin/sh
   2
   3test_description='git remote porcelain-ish'
   4
   5. ./test-lib.sh
   6
   7setup_repository () {
   8        mkdir "$1" && (
   9        cd "$1" &&
  10        git init &&
  11        >file &&
  12        git add file &&
  13        test_tick &&
  14        git commit -m "Initial" &&
  15        git checkout -b side &&
  16        >elif &&
  17        git add elif &&
  18        test_tick &&
  19        git commit -m "Second" &&
  20        git checkout master
  21        )
  22}
  23
  24tokens_match () {
  25        echo "$1" | tr ' ' '\012' | sort | sed -e '/^$/d' >expect &&
  26        echo "$2" | tr ' ' '\012' | sort | sed -e '/^$/d' >actual &&
  27        test_cmp expect actual
  28}
  29
  30check_remote_track () {
  31        actual=$(git remote show "$1" | sed -ne 's|^    \(.*\) tracked$|\1|p')
  32        shift &&
  33        tokens_match "$*" "$actual"
  34}
  35
  36check_tracking_branch () {
  37        f="" &&
  38        r=$(git for-each-ref "--format=%(refname)" |
  39                sed -ne "s|^refs/remotes/$1/||p") &&
  40        shift &&
  41        tokens_match "$*" "$r"
  42}
  43
  44test_expect_success setup '
  45
  46        setup_repository one &&
  47        setup_repository two &&
  48        (
  49                cd two && git branch another
  50        ) &&
  51        git clone one test
  52
  53'
  54
  55test_expect_success 'remote information for the origin' '
  56(
  57        cd test &&
  58        tokens_match origin "$(git remote)" &&
  59        check_remote_track origin master side &&
  60        check_tracking_branch origin HEAD master side
  61)
  62'
  63
  64test_expect_success 'add another remote' '
  65(
  66        cd test &&
  67        git remote add -f second ../two &&
  68        tokens_match "origin second" "$(git remote)" &&
  69        check_remote_track origin master side &&
  70        check_remote_track second master side another &&
  71        check_tracking_branch second master side another &&
  72        git for-each-ref "--format=%(refname)" refs/remotes |
  73        sed -e "/^refs\/remotes\/origin\//d" \
  74            -e "/^refs\/remotes\/second\//d" >actual &&
  75        >expect &&
  76        test_cmp expect actual
  77)
  78'
  79
  80test_expect_success 'remote forces tracking branches' '
  81(
  82        cd test &&
  83        case `git config remote.second.fetch` in
  84        +*) true ;;
  85         *) false ;;
  86        esac
  87)
  88'
  89
  90test_expect_success 'remove remote' '
  91(
  92        cd test &&
  93        git symbolic-ref refs/remotes/second/HEAD refs/remotes/second/master &&
  94        git remote rm second
  95)
  96'
  97
  98test_expect_success 'remove remote' '
  99(
 100        cd test &&
 101        tokens_match origin "$(git remote)" &&
 102        check_remote_track origin master side &&
 103        git for-each-ref "--format=%(refname)" refs/remotes |
 104        sed -e "/^refs\/remotes\/origin\//d" >actual &&
 105        >expect &&
 106        test_cmp expect actual
 107)
 108'
 109
 110test_expect_success 'remove remote protects non-remote branches' '
 111(
 112        cd test &&
 113        { cat >expect1 <<EOF
 114Note: A non-remote branch was not removed; to delete it, use:
 115  git branch -d master
 116EOF
 117        } &&
 118        { cat >expect2 <<EOF
 119Note: Non-remote branches were not removed; to delete them, use:
 120  git branch -d foobranch
 121  git branch -d master
 122EOF
 123        } &&
 124        git tag footag &&
 125        git config --add remote.oops.fetch "+refs/*:refs/*" &&
 126        git remote rm oops 2>actual1 &&
 127        git branch foobranch &&
 128        git config --add remote.oops.fetch "+refs/*:refs/*" &&
 129        git remote rm oops 2>actual2 &&
 130        git branch -d foobranch &&
 131        git tag -d footag &&
 132        test_cmp expect1 actual1 &&
 133        test_cmp expect2 actual2
 134)
 135'
 136
 137cat > test/expect << EOF
 138* remote origin
 139  Fetch URL: $(pwd)/one
 140  Push  URL: $(pwd)/one
 141  HEAD branch: master
 142  Remote branches:
 143    master new (next fetch will store in remotes/origin)
 144    side   tracked
 145  Local branches configured for 'git pull':
 146    ahead    merges with remote master
 147    master   merges with remote master
 148    octopus  merges with remote topic-a
 149                and with remote topic-b
 150                and with remote topic-c
 151    rebase  rebases onto remote master
 152  Local refs configured for 'git push':
 153    master pushes to master   (local out of date)
 154    master pushes to upstream (create)
 155* remote two
 156  Fetch URL: ../two
 157  Push  URL: ../three
 158  HEAD branch (remote HEAD is ambiguous, may be one of the following):
 159    another
 160    master
 161  Local refs configured for 'git push':
 162    ahead  forces to master  (fast-forwardable)
 163    master pushes to another (up to date)
 164EOF
 165
 166test_expect_success 'show' '
 167        (cd test &&
 168         git config --add remote.origin.fetch refs/heads/master:refs/heads/upstream &&
 169         git fetch &&
 170         git checkout -b ahead origin/master &&
 171         echo 1 >> file &&
 172         test_tick &&
 173         git commit -m update file &&
 174         git checkout master &&
 175         git branch --track octopus origin/master &&
 176         git branch --track rebase origin/master &&
 177         git branch -d -r origin/master &&
 178         git config --add remote.two.url ../two &&
 179         git config --add remote.two.pushurl ../three &&
 180         git config branch.rebase.rebase true &&
 181         git config branch.octopus.merge "topic-a topic-b topic-c" &&
 182         (cd ../one &&
 183          echo 1 > file &&
 184          test_tick &&
 185          git commit -m update file) &&
 186         git config --add remote.origin.push : &&
 187         git config --add remote.origin.push refs/heads/master:refs/heads/upstream &&
 188         git config --add remote.origin.push +refs/tags/lastbackup &&
 189         git config --add remote.two.push +refs/heads/ahead:refs/heads/master &&
 190         git config --add remote.two.push refs/heads/master:refs/heads/another &&
 191         git remote show origin two > output &&
 192         git branch -d rebase octopus &&
 193         test_cmp expect output)
 194'
 195
 196cat > test/expect << EOF
 197* remote origin
 198  Fetch URL: $(pwd)/one
 199  Push  URL: $(pwd)/one
 200  HEAD branch: (not queried)
 201  Remote branches: (status not queried)
 202    master
 203    side
 204  Local branches configured for 'git pull':
 205    ahead  merges with remote master
 206    master merges with remote master
 207  Local refs configured for 'git push' (status not queried):
 208    (matching)           pushes to (matching)
 209    refs/heads/master    pushes to refs/heads/upstream
 210    refs/tags/lastbackup forces to refs/tags/lastbackup
 211EOF
 212
 213test_expect_success 'show -n' '
 214        (mv one one.unreachable &&
 215         cd test &&
 216         git remote show -n origin > output &&
 217         mv ../one.unreachable ../one &&
 218         test_cmp expect output)
 219'
 220
 221test_expect_success 'prune' '
 222        (cd one &&
 223         git branch -m side side2) &&
 224        (cd test &&
 225         git fetch origin &&
 226         git remote prune origin &&
 227         git rev-parse refs/remotes/origin/side2 &&
 228         test_must_fail git rev-parse refs/remotes/origin/side)
 229'
 230
 231test_expect_success 'set-head --delete' '
 232        (cd test &&
 233         git symbolic-ref refs/remotes/origin/HEAD &&
 234         git remote set-head --delete origin &&
 235         test_must_fail git symbolic-ref refs/remotes/origin/HEAD)
 236'
 237
 238test_expect_success 'set-head --auto' '
 239        (cd test &&
 240         git remote set-head --auto origin &&
 241         echo refs/remotes/origin/master >expect &&
 242         git symbolic-ref refs/remotes/origin/HEAD >output &&
 243         test_cmp expect output
 244        )
 245'
 246
 247cat >test/expect <<EOF
 248error: Multiple remote HEAD branches. Please choose one explicitly with:
 249  git remote set-head two another
 250  git remote set-head two master
 251EOF
 252
 253test_expect_success 'set-head --auto fails w/multiple HEADs' '
 254        (cd test &&
 255         test_must_fail git remote set-head --auto two >output 2>&1 &&
 256        test_cmp expect output)
 257'
 258
 259cat >test/expect <<EOF
 260refs/remotes/origin/side2
 261EOF
 262
 263test_expect_success 'set-head explicit' '
 264        (cd test &&
 265         git remote set-head origin side2 &&
 266         git symbolic-ref refs/remotes/origin/HEAD >output &&
 267         git remote set-head origin master &&
 268         test_cmp expect output)
 269'
 270
 271cat > test/expect << EOF
 272Pruning origin
 273URL: $(pwd)/one
 274 * [would prune] origin/side2
 275EOF
 276
 277test_expect_success 'prune --dry-run' '
 278        (cd one &&
 279         git branch -m side2 side) &&
 280        (cd test &&
 281         git remote prune --dry-run origin > output &&
 282         git rev-parse refs/remotes/origin/side2 &&
 283         test_must_fail git rev-parse refs/remotes/origin/side &&
 284        (cd ../one &&
 285         git branch -m side side2) &&
 286         test_cmp expect output)
 287'
 288
 289test_expect_success 'add --mirror && prune' '
 290        (mkdir mirror &&
 291         cd mirror &&
 292         git init --bare &&
 293         git remote add --mirror -f origin ../one) &&
 294        (cd one &&
 295         git branch -m side2 side) &&
 296        (cd mirror &&
 297         git rev-parse --verify refs/heads/side2 &&
 298         test_must_fail git rev-parse --verify refs/heads/side &&
 299         git fetch origin &&
 300         git remote prune origin &&
 301         test_must_fail git rev-parse --verify refs/heads/side2 &&
 302         git rev-parse --verify refs/heads/side)
 303'
 304
 305test_expect_success 'add alt && prune' '
 306        (mkdir alttst &&
 307         cd alttst &&
 308         git init &&
 309         git remote add -f origin ../one &&
 310         git config remote.alt.url ../one &&
 311         git config remote.alt.fetch "+refs/heads/*:refs/remotes/origin/*") &&
 312        (cd one &&
 313         git branch -m side side2) &&
 314        (cd alttst &&
 315         git rev-parse --verify refs/remotes/origin/side &&
 316         test_must_fail git rev-parse --verify refs/remotes/origin/side2 &&
 317         git fetch alt &&
 318         git remote prune alt &&
 319         test_must_fail git rev-parse --verify refs/remotes/origin/side &&
 320         git rev-parse --verify refs/remotes/origin/side2)
 321'
 322
 323cat > one/expect << EOF
 324  apis/master
 325  apis/side
 326  drosophila/another
 327  drosophila/master
 328  drosophila/side
 329EOF
 330
 331test_expect_success 'update' '
 332
 333        (cd one &&
 334         git remote add drosophila ../two &&
 335         git remote add apis ../mirror &&
 336         git remote update &&
 337         git branch -r > output &&
 338         test_cmp expect output)
 339
 340'
 341
 342cat > one/expect << EOF
 343  drosophila/another
 344  drosophila/master
 345  drosophila/side
 346  manduca/master
 347  manduca/side
 348  megaloprepus/master
 349  megaloprepus/side
 350EOF
 351
 352test_expect_success 'update with arguments' '
 353
 354        (cd one &&
 355         for b in $(git branch -r)
 356         do
 357                git branch -r -d $b || break
 358         done &&
 359         git remote add manduca ../mirror &&
 360         git remote add megaloprepus ../mirror &&
 361         git config remotes.phobaeticus "drosophila megaloprepus" &&
 362         git config remotes.titanus manduca &&
 363         git remote update phobaeticus titanus &&
 364         git branch -r > output &&
 365         test_cmp expect output)
 366
 367'
 368
 369test_expect_success 'update --prune' '
 370
 371        (cd one &&
 372         git branch -m side2 side3) &&
 373        (cd test &&
 374         git remote update --prune &&
 375         (cd ../one && git branch -m side3 side2)
 376         git rev-parse refs/remotes/origin/side3 &&
 377         test_must_fail git rev-parse refs/remotes/origin/side2)
 378'
 379
 380cat > one/expect << EOF
 381  apis/master
 382  apis/side
 383  manduca/master
 384  manduca/side
 385  megaloprepus/master
 386  megaloprepus/side
 387EOF
 388
 389test_expect_success 'update default' '
 390
 391        (cd one &&
 392         for b in $(git branch -r)
 393         do
 394                git branch -r -d $b || break
 395         done &&
 396         git config remote.drosophila.skipDefaultUpdate true &&
 397         git remote update default &&
 398         git branch -r > output &&
 399         test_cmp expect output)
 400
 401'
 402
 403cat > one/expect << EOF
 404  drosophila/another
 405  drosophila/master
 406  drosophila/side
 407EOF
 408
 409test_expect_success 'update default (overridden, with funny whitespace)' '
 410
 411        (cd one &&
 412         for b in $(git branch -r)
 413         do
 414                git branch -r -d $b || break
 415         done &&
 416         git config remotes.default "$(printf "\t drosophila  \n")" &&
 417         git remote update default &&
 418         git branch -r > output &&
 419         test_cmp expect output)
 420
 421'
 422
 423test_expect_success 'update (with remotes.default defined)' '
 424
 425        (cd one &&
 426         for b in $(git branch -r)
 427         do
 428                git branch -r -d $b || break
 429         done &&
 430         git config remotes.default "drosophila" &&
 431         git remote update &&
 432         git branch -r > output &&
 433         test_cmp expect output)
 434
 435'
 436
 437test_expect_success '"remote show" does not show symbolic refs' '
 438
 439        git clone one three &&
 440        (cd three &&
 441         git remote show origin > output &&
 442         ! grep "^ *HEAD$" < output &&
 443         ! grep -i stale < output)
 444
 445'
 446
 447test_expect_success 'reject adding remote with an invalid name' '
 448
 449        test_must_fail git remote add some:url desired-name
 450
 451'
 452
 453# The first three test if the tracking branches are properly renamed,
 454# the last two ones check if the config is updated.
 455
 456test_expect_success 'rename a remote' '
 457
 458        git clone one four &&
 459        (cd four &&
 460         git remote rename origin upstream &&
 461         rmdir .git/refs/remotes/origin &&
 462         test "$(git symbolic-ref refs/remotes/upstream/HEAD)" = "refs/remotes/upstream/master" &&
 463         test "$(git rev-parse upstream/master)" = "$(git rev-parse master)" &&
 464         test "$(git config remote.upstream.fetch)" = "+refs/heads/*:refs/remotes/upstream/*" &&
 465         test "$(git config branch.master.remote)" = "upstream")
 466
 467'
 468
 469cat > remotes_origin << EOF
 470URL: $(pwd)/one
 471Push: refs/heads/master:refs/heads/upstream
 472Pull: refs/heads/master:refs/heads/origin
 473EOF
 474
 475test_expect_success 'migrate a remote from named file in $GIT_DIR/remotes' '
 476        git clone one five &&
 477        origin_url=$(pwd)/one &&
 478        (cd five &&
 479         git remote rm origin &&
 480         mkdir -p .git/remotes &&
 481         cat ../remotes_origin > .git/remotes/origin &&
 482         git remote rename origin origin &&
 483         ! test -f .git/remotes/origin &&
 484         test "$(git config remote.origin.url)" = "$origin_url" &&
 485         test "$(git config remote.origin.push)" = "refs/heads/master:refs/heads/upstream" &&
 486         test "$(git config remote.origin.fetch)" = "refs/heads/master:refs/heads/origin")
 487'
 488
 489test_expect_success 'migrate a remote from named file in $GIT_DIR/branches' '
 490        git clone one six &&
 491        origin_url=$(pwd)/one &&
 492        (cd six &&
 493         git remote rm origin &&
 494         echo "$origin_url" > .git/branches/origin &&
 495         git remote rename origin origin &&
 496         ! test -f .git/branches/origin &&
 497         test "$(git config remote.origin.url)" = "$origin_url" &&
 498         test "$(git config remote.origin.fetch)" = "refs/heads/master:refs/heads/origin")
 499'
 500
 501test_expect_success 'remote prune to cause a dangling symref' '
 502        git clone one seven &&
 503        (
 504                cd one &&
 505                git checkout side2 &&
 506                git branch -D master
 507        ) &&
 508        (
 509                cd seven &&
 510                git remote prune origin
 511        ) >err 2>&1 &&
 512        grep "has become dangling" err &&
 513
 514        : And the dangling symref will not cause other annoying errors &&
 515        (
 516                cd seven &&
 517                git branch -a
 518        ) 2>err &&
 519        ! grep "points nowhere" err &&
 520        (
 521                cd seven &&
 522                test_must_fail git branch nomore origin
 523        ) 2>err &&
 524        grep "dangling symref" err
 525'
 526
 527test_expect_success 'show empty remote' '
 528
 529        test_create_repo empty &&
 530        git clone empty empty-clone &&
 531        (
 532                cd empty-clone &&
 533                git remote show origin
 534        )
 535'
 536
 537test_expect_success 'new remote' '
 538        git remote add someremote foo &&
 539        echo foo >expect &&
 540        git config --get-all remote.someremote.url >actual &&
 541        cmp expect actual
 542'
 543
 544test_expect_success 'remote set-url bar' '
 545        git remote set-url someremote bar &&
 546        echo bar >expect &&
 547        git config --get-all remote.someremote.url >actual &&
 548        cmp expect actual
 549'
 550
 551test_expect_success 'remote set-url baz bar' '
 552        git remote set-url someremote baz bar &&
 553        echo baz >expect &&
 554        git config --get-all remote.someremote.url >actual &&
 555        cmp expect actual
 556'
 557
 558test_expect_success 'remote set-url zot bar' '
 559        test_must_fail git remote set-url someremote zot bar &&
 560        echo baz >expect &&
 561        git config --get-all remote.someremote.url >actual &&
 562        cmp expect actual
 563'
 564
 565test_expect_success 'remote set-url --push zot baz' '
 566        test_must_fail git remote set-url --push someremote zot baz &&
 567        echo "YYY" >expect &&
 568        echo baz >>expect &&
 569        test_must_fail git config --get-all remote.someremote.pushurl >actual &&
 570        echo "YYY" >>actual &&
 571        git config --get-all remote.someremote.url >>actual &&
 572        cmp expect actual
 573'
 574
 575test_expect_success 'remote set-url --push zot' '
 576        git remote set-url --push someremote zot &&
 577        echo zot >expect &&
 578        echo "YYY" >>expect &&
 579        echo baz >>expect &&
 580        git config --get-all remote.someremote.pushurl >actual &&
 581        echo "YYY" >>actual &&
 582        git config --get-all remote.someremote.url >>actual &&
 583        cmp expect actual
 584'
 585
 586test_expect_success 'remote set-url --push qux zot' '
 587        git remote set-url --push someremote qux zot &&
 588        echo qux >expect &&
 589        echo "YYY" >>expect &&
 590        echo baz >>expect &&
 591        git config --get-all remote.someremote.pushurl >actual &&
 592        echo "YYY" >>actual &&
 593        git config --get-all remote.someremote.url >>actual &&
 594        cmp expect actual
 595'
 596
 597test_expect_success 'remote set-url --push foo qu+x' '
 598        git remote set-url --push someremote foo qu+x &&
 599        echo foo >expect &&
 600        echo "YYY" >>expect &&
 601        echo baz >>expect &&
 602        git config --get-all remote.someremote.pushurl >actual &&
 603        echo "YYY" >>actual &&
 604        git config --get-all remote.someremote.url >>actual &&
 605        cmp expect actual
 606'
 607
 608test_expect_success 'remote set-url --push --add aaa' '
 609        git remote set-url --push --add someremote aaa &&
 610        echo foo >expect &&
 611        echo aaa >>expect &&
 612        echo "YYY" >>expect &&
 613        echo baz >>expect &&
 614        git config --get-all remote.someremote.pushurl >actual &&
 615        echo "YYY" >>actual &&
 616        git config --get-all remote.someremote.url >>actual &&
 617        cmp expect actual
 618'
 619
 620test_expect_success 'remote set-url --push bar aaa' '
 621        git remote set-url --push someremote bar aaa &&
 622        echo foo >expect &&
 623        echo bar >>expect &&
 624        echo "YYY" >>expect &&
 625        echo baz >>expect &&
 626        git config --get-all remote.someremote.pushurl >actual &&
 627        echo "YYY" >>actual &&
 628        git config --get-all remote.someremote.url >>actual &&
 629        cmp expect actual
 630'
 631
 632test_expect_success 'remote set-url --push --delete bar' '
 633        git remote set-url --push --delete someremote bar &&
 634        echo foo >expect &&
 635        echo "YYY" >>expect &&
 636        echo baz >>expect &&
 637        git config --get-all remote.someremote.pushurl >actual &&
 638        echo "YYY" >>actual &&
 639        git config --get-all remote.someremote.url >>actual &&
 640        cmp expect actual
 641'
 642
 643test_expect_success 'remote set-url --push --delete foo' '
 644        git remote set-url --push --delete someremote foo &&
 645        echo "YYY" >expect &&
 646        echo baz >>expect &&
 647        test_must_fail git config --get-all remote.someremote.pushurl >actual &&
 648        echo "YYY" >>actual &&
 649        git config --get-all remote.someremote.url >>actual &&
 650        cmp expect actual
 651'
 652
 653test_expect_success 'remote set-url --add bbb' '
 654        git remote set-url --add someremote bbb &&
 655        echo "YYY" >expect &&
 656        echo baz >>expect &&
 657        echo bbb >>expect &&
 658        test_must_fail git config --get-all remote.someremote.pushurl >actual &&
 659        echo "YYY" >>actual &&
 660        git config --get-all remote.someremote.url >>actual &&
 661        cmp expect actual
 662'
 663
 664test_expect_success 'remote set-url --delete .*' '
 665        test_must_fail git remote set-url --delete someremote .\* &&
 666        echo "YYY" >expect &&
 667        echo baz >>expect &&
 668        echo bbb >>expect &&
 669        test_must_fail git config --get-all remote.someremote.pushurl >actual &&
 670        echo "YYY" >>actual &&
 671        git config --get-all remote.someremote.url >>actual &&
 672        cmp expect actual
 673'
 674
 675test_expect_success 'remote set-url --delete bbb' '
 676        git remote set-url --delete someremote bbb &&
 677        echo "YYY" >expect &&
 678        echo baz >>expect &&
 679        test_must_fail git config --get-all remote.someremote.pushurl >actual &&
 680        echo "YYY" >>actual &&
 681        git config --get-all remote.someremote.url >>actual &&
 682        cmp expect actual
 683'
 684
 685test_expect_success 'remote set-url --delete baz' '
 686        test_must_fail git remote set-url --delete someremote baz &&
 687        echo "YYY" >expect &&
 688        echo baz >>expect &&
 689        test_must_fail git config --get-all remote.someremote.pushurl >actual &&
 690        echo "YYY" >>actual &&
 691        git config --get-all remote.someremote.url >>actual &&
 692        cmp expect actual
 693'
 694
 695test_expect_success 'remote set-url --add ccc' '
 696        git remote set-url --add someremote ccc &&
 697        echo "YYY" >expect &&
 698        echo baz >>expect &&
 699        echo ccc >>expect &&
 700        test_must_fail git config --get-all remote.someremote.pushurl >actual &&
 701        echo "YYY" >>actual &&
 702        git config --get-all remote.someremote.url >>actual &&
 703        cmp expect actual
 704'
 705
 706test_expect_success 'remote set-url --delete baz' '
 707        git remote set-url --delete someremote baz &&
 708        echo "YYY" >expect &&
 709        echo ccc >>expect &&
 710        test_must_fail git config --get-all remote.someremote.pushurl >actual &&
 711        echo "YYY" >>actual &&
 712        git config --get-all remote.someremote.url >>actual &&
 713        cmp expect actual
 714'
 715
 716test_done