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