t / t5510-fetch.shon commit t4014: fix arguments to grep (27f6342)
   1#!/bin/sh
   2# Copyright (c) 2006, Junio C Hamano.
   3
   4test_description='Per branch config variables affects "git fetch".
   5
   6'
   7
   8. ./test-lib.sh
   9
  10D=`pwd`
  11
  12test_bundle_object_count () {
  13        git verify-pack -v "$1" >verify.out &&
  14        test "$2" = $(grep '^[0-9a-f]\{40\} ' verify.out | wc -l)
  15}
  16
  17convert_bundle_to_pack () {
  18        while read x && test -n "$x"
  19        do
  20                :;
  21        done
  22        cat
  23}
  24
  25test_expect_success setup '
  26        echo >file original &&
  27        git add file &&
  28        git commit -a -m original'
  29
  30test_expect_success "clone and setup child repos" '
  31        git clone . one &&
  32        (
  33                cd one &&
  34                echo >file updated by one &&
  35                git commit -a -m "updated by one"
  36        ) &&
  37        git clone . two &&
  38        (
  39                cd two &&
  40                git config branch.master.remote one &&
  41                git config remote.one.url ../one/.git/ &&
  42                git config remote.one.fetch refs/heads/master:refs/heads/one
  43        ) &&
  44        git clone . three &&
  45        (
  46                cd three &&
  47                git config branch.master.remote two &&
  48                git config branch.master.merge refs/heads/one &&
  49                mkdir -p .git/remotes &&
  50                {
  51                        echo "URL: ../two/.git/"
  52                        echo "Pull: refs/heads/master:refs/heads/two"
  53                        echo "Pull: refs/heads/one:refs/heads/one"
  54                } >.git/remotes/two
  55        ) &&
  56        git clone . bundle &&
  57        git clone . seven
  58'
  59
  60test_expect_success "fetch test" '
  61        cd "$D" &&
  62        echo >file updated by origin &&
  63        git commit -a -m "updated by origin" &&
  64        cd two &&
  65        git fetch &&
  66        test -f .git/refs/heads/one &&
  67        mine=`git rev-parse refs/heads/one` &&
  68        his=`cd ../one && git rev-parse refs/heads/master` &&
  69        test "z$mine" = "z$his"
  70'
  71
  72test_expect_success "fetch test for-merge" '
  73        cd "$D" &&
  74        cd three &&
  75        git fetch &&
  76        test -f .git/refs/heads/two &&
  77        test -f .git/refs/heads/one &&
  78        master_in_two=`cd ../two && git rev-parse master` &&
  79        one_in_two=`cd ../two && git rev-parse one` &&
  80        {
  81                echo "$one_in_two       "
  82                echo "$master_in_two    not-for-merge"
  83        } >expected &&
  84        cut -f -2 .git/FETCH_HEAD >actual &&
  85        test_cmp expected actual'
  86
  87test_expect_success 'fetch --prune on its own works as expected' '
  88        cd "$D" &&
  89        git clone . prune &&
  90        cd prune &&
  91        git fetch origin refs/heads/master:refs/remotes/origin/extrabranch &&
  92
  93        git fetch --prune origin &&
  94        test_must_fail git rev-parse origin/extrabranch
  95'
  96
  97test_expect_success 'fetch --prune with a branch name keeps branches' '
  98        cd "$D" &&
  99        git clone . prune-branch &&
 100        cd prune-branch &&
 101        git fetch origin refs/heads/master:refs/remotes/origin/extrabranch &&
 102
 103        git fetch --prune origin master &&
 104        git rev-parse origin/extrabranch
 105'
 106
 107test_expect_success 'fetch --prune with a namespace keeps other namespaces' '
 108        cd "$D" &&
 109        git clone . prune-namespace &&
 110        cd prune-namespace &&
 111
 112        git fetch --prune origin refs/heads/a/*:refs/remotes/origin/a/* &&
 113        git rev-parse origin/master
 114'
 115
 116test_expect_success 'fetch --prune --tags does not delete the remote-tracking branches' '
 117        cd "$D" &&
 118        git clone . prune-tags &&
 119        cd prune-tags &&
 120        git fetch origin refs/heads/master:refs/tags/sometag &&
 121
 122        git fetch --prune --tags origin &&
 123        git rev-parse origin/master &&
 124        test_must_fail git rev-parse somebranch
 125'
 126
 127test_expect_success 'fetch --prune --tags with branch does not delete other remote-tracking branches' '
 128        cd "$D" &&
 129        git clone . prune-tags-branch &&
 130        cd prune-tags-branch &&
 131        git fetch origin refs/heads/master:refs/remotes/origin/extrabranch &&
 132
 133        git fetch --prune --tags origin master &&
 134        git rev-parse origin/extrabranch
 135'
 136
 137test_expect_success 'fetch tags when there is no tags' '
 138
 139    cd "$D" &&
 140
 141    mkdir notags &&
 142    cd notags &&
 143    git init &&
 144
 145    git fetch -t ..
 146
 147'
 148
 149test_expect_success 'fetch following tags' '
 150
 151        cd "$D" &&
 152        git tag -a -m 'annotated' anno HEAD &&
 153        git tag light HEAD &&
 154
 155        mkdir four &&
 156        cd four &&
 157        git init &&
 158
 159        git fetch .. :track &&
 160        git show-ref --verify refs/tags/anno &&
 161        git show-ref --verify refs/tags/light
 162
 163'
 164
 165test_expect_success 'fetch uses remote ref names to describe new refs' '
 166        cd "$D" &&
 167        git init descriptive &&
 168        (
 169                cd descriptive &&
 170                git config remote.o.url .. &&
 171                git config remote.o.fetch "refs/heads/*:refs/crazyheads/*" &&
 172                git config --add remote.o.fetch "refs/others/*:refs/heads/*" &&
 173                git fetch o
 174        ) &&
 175        git tag -a -m "Descriptive tag" descriptive-tag &&
 176        git branch descriptive-branch &&
 177        git checkout descriptive-branch &&
 178        echo "Nuts" >crazy &&
 179        git add crazy &&
 180        git commit -a -m "descriptive commit" &&
 181        git update-ref refs/others/crazy HEAD &&
 182        (
 183                cd descriptive &&
 184                git fetch o 2>actual &&
 185                grep " -> refs/crazyheads/descriptive-branch$" actual |
 186                test_i18ngrep "new branch" &&
 187                grep " -> descriptive-tag$" actual |
 188                test_i18ngrep "new tag" &&
 189                grep " -> crazy$" actual |
 190                test_i18ngrep "new ref"
 191        ) &&
 192        git checkout master
 193'
 194
 195test_expect_success 'fetch must not resolve short tag name' '
 196
 197        cd "$D" &&
 198
 199        mkdir five &&
 200        cd five &&
 201        git init &&
 202
 203        test_must_fail git fetch .. anno:five
 204
 205'
 206
 207test_expect_success 'fetch can now resolve short remote name' '
 208
 209        cd "$D" &&
 210        git update-ref refs/remotes/six/HEAD HEAD &&
 211
 212        mkdir six &&
 213        cd six &&
 214        git init &&
 215
 216        git fetch .. six:six
 217'
 218
 219test_expect_success 'create bundle 1' '
 220        cd "$D" &&
 221        echo >file updated again by origin &&
 222        git commit -a -m "tip" &&
 223        git bundle create bundle1 master^..master
 224'
 225
 226test_expect_success 'header of bundle looks right' '
 227        head -n 1 "$D"/bundle1 | grep "^#" &&
 228        head -n 2 "$D"/bundle1 | grep "^-[0-9a-f]\{40\} " &&
 229        head -n 3 "$D"/bundle1 | grep "^[0-9a-f]\{40\} " &&
 230        head -n 4 "$D"/bundle1 | grep "^$"
 231'
 232
 233test_expect_success 'create bundle 2' '
 234        cd "$D" &&
 235        git bundle create bundle2 master~2..master
 236'
 237
 238test_expect_success 'unbundle 1' '
 239        cd "$D/bundle" &&
 240        git checkout -b some-branch &&
 241        test_must_fail git fetch "$D/bundle1" master:master
 242'
 243
 244
 245test_expect_success 'bundle 1 has only 3 files ' '
 246        cd "$D" &&
 247        convert_bundle_to_pack <bundle1 >bundle.pack &&
 248        git index-pack bundle.pack &&
 249        test_bundle_object_count bundle.pack 3
 250'
 251
 252test_expect_success 'unbundle 2' '
 253        cd "$D/bundle" &&
 254        git fetch ../bundle2 master:master &&
 255        test "tip" = "$(git log -1 --pretty=oneline master | cut -b42-)"
 256'
 257
 258test_expect_success 'bundle does not prerequisite objects' '
 259        cd "$D" &&
 260        touch file2 &&
 261        git add file2 &&
 262        git commit -m add.file2 file2 &&
 263        git bundle create bundle3 -1 HEAD &&
 264        convert_bundle_to_pack <bundle3 >bundle.pack &&
 265        git index-pack bundle.pack &&
 266        test_bundle_object_count bundle.pack 3
 267'
 268
 269test_expect_success 'bundle should be able to create a full history' '
 270
 271        cd "$D" &&
 272        git tag -a -m '1.0' v1.0 master &&
 273        git bundle create bundle4 v1.0
 274
 275'
 276
 277! rsync --help > /dev/null 2> /dev/null &&
 278say 'Skipping rsync tests because rsync was not found' || {
 279test_expect_success 'fetch via rsync' '
 280        git pack-refs &&
 281        mkdir rsynced &&
 282        (cd rsynced &&
 283         git init --bare &&
 284         git fetch "rsync:$(pwd)/../.git" master:refs/heads/master &&
 285         git gc --prune &&
 286         test $(git rev-parse master) = $(cd .. && git rev-parse master) &&
 287         git fsck --full)
 288'
 289
 290test_expect_success 'push via rsync' '
 291        mkdir rsynced2 &&
 292        (cd rsynced2 &&
 293         git init) &&
 294        (cd rsynced &&
 295         git push "rsync:$(pwd)/../rsynced2/.git" master) &&
 296        (cd rsynced2 &&
 297         git gc --prune &&
 298         test $(git rev-parse master) = $(cd .. && git rev-parse master) &&
 299         git fsck --full)
 300'
 301
 302test_expect_success 'push via rsync' '
 303        mkdir rsynced3 &&
 304        (cd rsynced3 &&
 305         git init) &&
 306        git push --all "rsync:$(pwd)/rsynced3/.git" &&
 307        (cd rsynced3 &&
 308         test $(git rev-parse master) = $(cd .. && git rev-parse master) &&
 309         git fsck --full)
 310'
 311}
 312
 313test_expect_success 'fetch with a non-applying branch.<name>.merge' '
 314        git config branch.master.remote yeti &&
 315        git config branch.master.merge refs/heads/bigfoot &&
 316        git config remote.blub.url one &&
 317        git config remote.blub.fetch "refs/heads/*:refs/remotes/one/*" &&
 318        git fetch blub
 319'
 320
 321# URL supplied to fetch does not match the url of the configured branch's remote
 322test_expect_success 'fetch from GIT URL with a non-applying branch.<name>.merge [1]' '
 323        one_head=$(cd one && git rev-parse HEAD) &&
 324        this_head=$(git rev-parse HEAD) &&
 325        git update-ref -d FETCH_HEAD &&
 326        git fetch one &&
 327        test $one_head = "$(git rev-parse --verify FETCH_HEAD)" &&
 328        test $this_head = "$(git rev-parse --verify HEAD)"
 329'
 330
 331# URL supplied to fetch matches the url of the configured branch's remote and
 332# the merge spec matches the branch the remote HEAD points to
 333test_expect_success 'fetch from GIT URL with a non-applying branch.<name>.merge [2]' '
 334        one_ref=$(cd one && git symbolic-ref HEAD) &&
 335        git config branch.master.remote blub &&
 336        git config branch.master.merge "$one_ref" &&
 337        git update-ref -d FETCH_HEAD &&
 338        git fetch one &&
 339        test $one_head = "$(git rev-parse --verify FETCH_HEAD)" &&
 340        test $this_head = "$(git rev-parse --verify HEAD)"
 341'
 342
 343# URL supplied to fetch matches the url of the configured branch's remote, but
 344# the merge spec does not match the branch the remote HEAD points to
 345test_expect_success 'fetch from GIT URL with a non-applying branch.<name>.merge [3]' '
 346        git config branch.master.merge "${one_ref}_not" &&
 347        git update-ref -d FETCH_HEAD &&
 348        git fetch one &&
 349        test $one_head = "$(git rev-parse --verify FETCH_HEAD)" &&
 350        test $this_head = "$(git rev-parse --verify HEAD)"
 351'
 352
 353# the strange name is: a\!'b
 354test_expect_success 'quoting of a strangely named repo' '
 355        test_must_fail git fetch "a\\!'\''b" > result 2>&1 &&
 356        cat result &&
 357        grep "fatal: '\''a\\\\!'\''b'\''" result
 358'
 359
 360test_expect_success 'bundle should record HEAD correctly' '
 361
 362        cd "$D" &&
 363        git bundle create bundle5 HEAD master &&
 364        git bundle list-heads bundle5 >actual &&
 365        for h in HEAD refs/heads/master
 366        do
 367                echo "$(git rev-parse --verify $h) $h"
 368        done >expect &&
 369        test_cmp expect actual
 370
 371'
 372
 373test_expect_success 'explicit fetch should not update tracking' '
 374
 375        cd "$D" &&
 376        git branch -f side &&
 377        (
 378                cd three &&
 379                o=$(git rev-parse --verify refs/remotes/origin/master) &&
 380                git fetch origin master &&
 381                n=$(git rev-parse --verify refs/remotes/origin/master) &&
 382                test "$o" = "$n" &&
 383                test_must_fail git rev-parse --verify refs/remotes/origin/side
 384        )
 385'
 386
 387test_expect_success 'explicit pull should not update tracking' '
 388
 389        cd "$D" &&
 390        git branch -f side &&
 391        (
 392                cd three &&
 393                o=$(git rev-parse --verify refs/remotes/origin/master) &&
 394                git pull origin master &&
 395                n=$(git rev-parse --verify refs/remotes/origin/master) &&
 396                test "$o" = "$n" &&
 397                test_must_fail git rev-parse --verify refs/remotes/origin/side
 398        )
 399'
 400
 401test_expect_success 'configured fetch updates tracking' '
 402
 403        cd "$D" &&
 404        git branch -f side &&
 405        (
 406                cd three &&
 407                o=$(git rev-parse --verify refs/remotes/origin/master) &&
 408                git fetch origin &&
 409                n=$(git rev-parse --verify refs/remotes/origin/master) &&
 410                test "$o" != "$n" &&
 411                git rev-parse --verify refs/remotes/origin/side
 412        )
 413'
 414
 415test_expect_success 'pushing nonexistent branch by mistake should not segv' '
 416
 417        cd "$D" &&
 418        test_must_fail git push seven no:no
 419
 420'
 421
 422test_expect_success 'auto tag following fetches minimum' '
 423
 424        cd "$D" &&
 425        git clone .git follow &&
 426        git checkout HEAD^0 &&
 427        (
 428                for i in 1 2 3 4 5 6 7
 429                do
 430                        echo $i >>file &&
 431                        git commit -m $i -a &&
 432                        git tag -a -m $i excess-$i || exit 1
 433                done
 434        ) &&
 435        git checkout master &&
 436        (
 437                cd follow &&
 438                git fetch
 439        )
 440'
 441
 442test_expect_success 'refuse to fetch into the current branch' '
 443
 444        test_must_fail git fetch . side:master
 445
 446'
 447
 448test_expect_success 'fetch into the current branch with --update-head-ok' '
 449
 450        git fetch --update-head-ok . side:master
 451
 452'
 453
 454test_expect_success 'fetch --dry-run' '
 455
 456        rm -f .git/FETCH_HEAD &&
 457        git fetch --dry-run . &&
 458        ! test -f .git/FETCH_HEAD
 459'
 460
 461test_expect_success "should be able to fetch with duplicate refspecs" '
 462        mkdir dups &&
 463        (
 464                cd dups &&
 465                git init &&
 466                git config branch.master.remote three &&
 467                git config remote.three.url ../three/.git &&
 468                git config remote.three.fetch +refs/heads/*:refs/remotes/origin/* &&
 469                git config --add remote.three.fetch +refs/heads/*:refs/remotes/origin/* &&
 470                git fetch three
 471        )
 472'
 473
 474test_expect_success 'all boundary commits are excluded' '
 475        test_commit base &&
 476        test_commit oneside &&
 477        git checkout HEAD^ &&
 478        test_commit otherside &&
 479        git checkout master &&
 480        test_tick &&
 481        git merge otherside &&
 482        ad=$(git log --no-walk --format=%ad HEAD) &&
 483        git bundle create twoside-boundary.bdl master --since="$ad" &&
 484        convert_bundle_to_pack <twoside-boundary.bdl >twoside-boundary.pack &&
 485        pack=$(git index-pack --fix-thin --stdin <twoside-boundary.pack) &&
 486        test_bundle_object_count .git/objects/pack/pack-${pack##pack    }.pack 3
 487'
 488
 489test_done