t / t5510-fetch.shon commit sh-setup: protect from exported IFS (785063e)
   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 must not resolve short tag name' '
 166
 167        cd "$D" &&
 168
 169        mkdir five &&
 170        cd five &&
 171        git init &&
 172
 173        test_must_fail git fetch .. anno:five
 174
 175'
 176
 177test_expect_success 'fetch can now resolve short remote name' '
 178
 179        cd "$D" &&
 180        git update-ref refs/remotes/six/HEAD HEAD &&
 181
 182        mkdir six &&
 183        cd six &&
 184        git init &&
 185
 186        git fetch .. six:six
 187'
 188
 189test_expect_success 'create bundle 1' '
 190        cd "$D" &&
 191        echo >file updated again by origin &&
 192        git commit -a -m "tip" &&
 193        git bundle create bundle1 master^..master
 194'
 195
 196test_expect_success 'header of bundle looks right' '
 197        head -n 1 "$D"/bundle1 | grep "^#" &&
 198        head -n 2 "$D"/bundle1 | grep "^-[0-9a-f]\{40\} " &&
 199        head -n 3 "$D"/bundle1 | grep "^[0-9a-f]\{40\} " &&
 200        head -n 4 "$D"/bundle1 | grep "^$"
 201'
 202
 203test_expect_success 'create bundle 2' '
 204        cd "$D" &&
 205        git bundle create bundle2 master~2..master
 206'
 207
 208test_expect_success 'unbundle 1' '
 209        cd "$D/bundle" &&
 210        git checkout -b some-branch &&
 211        test_must_fail git fetch "$D/bundle1" master:master
 212'
 213
 214
 215test_expect_success 'bundle 1 has only 3 files ' '
 216        cd "$D" &&
 217        convert_bundle_to_pack <bundle1 >bundle.pack &&
 218        git index-pack bundle.pack &&
 219        test_bundle_object_count bundle.pack 3
 220'
 221
 222test_expect_success 'unbundle 2' '
 223        cd "$D/bundle" &&
 224        git fetch ../bundle2 master:master &&
 225        test "tip" = "$(git log -1 --pretty=oneline master | cut -b42-)"
 226'
 227
 228test_expect_success 'bundle does not prerequisite objects' '
 229        cd "$D" &&
 230        touch file2 &&
 231        git add file2 &&
 232        git commit -m add.file2 file2 &&
 233        git bundle create bundle3 -1 HEAD &&
 234        convert_bundle_to_pack <bundle3 >bundle.pack &&
 235        git index-pack bundle.pack &&
 236        test_bundle_object_count bundle.pack 3
 237'
 238
 239test_expect_success 'bundle should be able to create a full history' '
 240
 241        cd "$D" &&
 242        git tag -a -m '1.0' v1.0 master &&
 243        git bundle create bundle4 v1.0
 244
 245'
 246
 247! rsync --help > /dev/null 2> /dev/null &&
 248say 'Skipping rsync tests because rsync was not found' || {
 249test_expect_success 'fetch via rsync' '
 250        git pack-refs &&
 251        mkdir rsynced &&
 252        (cd rsynced &&
 253         git init --bare &&
 254         git fetch "rsync:$(pwd)/../.git" master:refs/heads/master &&
 255         git gc --prune &&
 256         test $(git rev-parse master) = $(cd .. && git rev-parse master) &&
 257         git fsck --full)
 258'
 259
 260test_expect_success 'push via rsync' '
 261        mkdir rsynced2 &&
 262        (cd rsynced2 &&
 263         git init) &&
 264        (cd rsynced &&
 265         git push "rsync:$(pwd)/../rsynced2/.git" master) &&
 266        (cd rsynced2 &&
 267         git gc --prune &&
 268         test $(git rev-parse master) = $(cd .. && git rev-parse master) &&
 269         git fsck --full)
 270'
 271
 272test_expect_success 'push via rsync' '
 273        mkdir rsynced3 &&
 274        (cd rsynced3 &&
 275         git init) &&
 276        git push --all "rsync:$(pwd)/rsynced3/.git" &&
 277        (cd rsynced3 &&
 278         test $(git rev-parse master) = $(cd .. && git rev-parse master) &&
 279         git fsck --full)
 280'
 281}
 282
 283test_expect_success 'fetch with a non-applying branch.<name>.merge' '
 284        git config branch.master.remote yeti &&
 285        git config branch.master.merge refs/heads/bigfoot &&
 286        git config remote.blub.url one &&
 287        git config remote.blub.fetch "refs/heads/*:refs/remotes/one/*" &&
 288        git fetch blub
 289'
 290
 291# URL supplied to fetch does not match the url of the configured branch's remote
 292test_expect_success 'fetch from GIT URL with a non-applying branch.<name>.merge [1]' '
 293        one_head=$(cd one && git rev-parse HEAD) &&
 294        this_head=$(git rev-parse HEAD) &&
 295        git update-ref -d FETCH_HEAD &&
 296        git fetch one &&
 297        test $one_head = "$(git rev-parse --verify FETCH_HEAD)" &&
 298        test $this_head = "$(git rev-parse --verify HEAD)"
 299'
 300
 301# URL supplied to fetch matches the url of the configured branch's remote and
 302# the merge spec matches the branch the remote HEAD points to
 303test_expect_success 'fetch from GIT URL with a non-applying branch.<name>.merge [2]' '
 304        one_ref=$(cd one && git symbolic-ref HEAD) &&
 305        git config branch.master.remote blub &&
 306        git config branch.master.merge "$one_ref" &&
 307        git update-ref -d FETCH_HEAD &&
 308        git fetch one &&
 309        test $one_head = "$(git rev-parse --verify FETCH_HEAD)" &&
 310        test $this_head = "$(git rev-parse --verify HEAD)"
 311'
 312
 313# URL supplied to fetch matches the url of the configured branch's remote, but
 314# the merge spec does not match the branch the remote HEAD points to
 315test_expect_success 'fetch from GIT URL with a non-applying branch.<name>.merge [3]' '
 316        git config branch.master.merge "${one_ref}_not" &&
 317        git update-ref -d FETCH_HEAD &&
 318        git fetch one &&
 319        test $one_head = "$(git rev-parse --verify FETCH_HEAD)" &&
 320        test $this_head = "$(git rev-parse --verify HEAD)"
 321'
 322
 323# the strange name is: a\!'b
 324test_expect_success 'quoting of a strangely named repo' '
 325        test_must_fail git fetch "a\\!'\''b" > result 2>&1 &&
 326        cat result &&
 327        grep "fatal: '\''a\\\\!'\''b'\''" result
 328'
 329
 330test_expect_success 'bundle should record HEAD correctly' '
 331
 332        cd "$D" &&
 333        git bundle create bundle5 HEAD master &&
 334        git bundle list-heads bundle5 >actual &&
 335        for h in HEAD refs/heads/master
 336        do
 337                echo "$(git rev-parse --verify $h) $h"
 338        done >expect &&
 339        test_cmp expect actual
 340
 341'
 342
 343test_expect_success 'explicit fetch should not update tracking' '
 344
 345        cd "$D" &&
 346        git branch -f side &&
 347        (
 348                cd three &&
 349                o=$(git rev-parse --verify refs/remotes/origin/master) &&
 350                git fetch origin master &&
 351                n=$(git rev-parse --verify refs/remotes/origin/master) &&
 352                test "$o" = "$n" &&
 353                test_must_fail git rev-parse --verify refs/remotes/origin/side
 354        )
 355'
 356
 357test_expect_success 'explicit pull should not update tracking' '
 358
 359        cd "$D" &&
 360        git branch -f side &&
 361        (
 362                cd three &&
 363                o=$(git rev-parse --verify refs/remotes/origin/master) &&
 364                git pull origin master &&
 365                n=$(git rev-parse --verify refs/remotes/origin/master) &&
 366                test "$o" = "$n" &&
 367                test_must_fail git rev-parse --verify refs/remotes/origin/side
 368        )
 369'
 370
 371test_expect_success 'configured fetch updates tracking' '
 372
 373        cd "$D" &&
 374        git branch -f side &&
 375        (
 376                cd three &&
 377                o=$(git rev-parse --verify refs/remotes/origin/master) &&
 378                git fetch origin &&
 379                n=$(git rev-parse --verify refs/remotes/origin/master) &&
 380                test "$o" != "$n" &&
 381                git rev-parse --verify refs/remotes/origin/side
 382        )
 383'
 384
 385test_expect_success 'pushing nonexistent branch by mistake should not segv' '
 386
 387        cd "$D" &&
 388        test_must_fail git push seven no:no
 389
 390'
 391
 392test_expect_success 'auto tag following fetches minimum' '
 393
 394        cd "$D" &&
 395        git clone .git follow &&
 396        git checkout HEAD^0 &&
 397        (
 398                for i in 1 2 3 4 5 6 7
 399                do
 400                        echo $i >>file &&
 401                        git commit -m $i -a &&
 402                        git tag -a -m $i excess-$i || exit 1
 403                done
 404        ) &&
 405        git checkout master &&
 406        (
 407                cd follow &&
 408                git fetch
 409        )
 410'
 411
 412test_expect_success 'refuse to fetch into the current branch' '
 413
 414        test_must_fail git fetch . side:master
 415
 416'
 417
 418test_expect_success 'fetch into the current branch with --update-head-ok' '
 419
 420        git fetch --update-head-ok . side:master
 421
 422'
 423
 424test_expect_success 'fetch --dry-run' '
 425
 426        rm -f .git/FETCH_HEAD &&
 427        git fetch --dry-run . &&
 428        ! test -f .git/FETCH_HEAD
 429'
 430
 431test_expect_success "should be able to fetch with duplicate refspecs" '
 432        mkdir dups &&
 433        (
 434                cd dups &&
 435                git init &&
 436                git config branch.master.remote three &&
 437                git config remote.three.url ../three/.git &&
 438                git config remote.three.fetch +refs/heads/*:refs/remotes/origin/* &&
 439                git config --add remote.three.fetch +refs/heads/*:refs/remotes/origin/* &&
 440                git fetch three
 441        )
 442'
 443
 444test_expect_success 'all boundary commits are excluded' '
 445        test_commit base &&
 446        test_commit oneside &&
 447        git checkout HEAD^ &&
 448        test_commit otherside &&
 449        git checkout master &&
 450        test_tick &&
 451        git merge otherside &&
 452        ad=$(git log --no-walk --format=%ad HEAD) &&
 453        git bundle create twoside-boundary.bdl master --since="$ad" &&
 454        convert_bundle_to_pack <twoside-boundary.bdl >twoside-boundary.pack &&
 455        pack=$(git index-pack --fix-thin --stdin <twoside-boundary.pack) &&
 456        test_bundle_object_count .git/objects/pack/pack-${pack##pack    }.pack 3
 457'
 458
 459test_done