t / t5601-clone.shon commit t0008: avoid absolute path (2b3abd4)
   1#!/bin/sh
   2
   3test_description=clone
   4
   5. ./test-lib.sh
   6
   7X=
   8test_have_prereq !MINGW || X=.exe
   9
  10test_expect_success setup '
  11
  12        rm -fr .git &&
  13        test_create_repo src &&
  14        (
  15                cd src &&
  16                >file &&
  17                git add file &&
  18                git commit -m initial &&
  19                echo 1 >file &&
  20                git add file &&
  21                git commit -m updated
  22        )
  23
  24'
  25
  26test_expect_success 'clone with excess parameters (1)' '
  27
  28        rm -fr dst &&
  29        test_must_fail git clone -n src dst junk
  30
  31'
  32
  33test_expect_success 'clone with excess parameters (2)' '
  34
  35        rm -fr dst &&
  36        test_must_fail git clone -n "file://$(pwd)/src" dst junk
  37
  38'
  39
  40test_expect_success C_LOCALE_OUTPUT 'output from clone' '
  41        rm -fr dst &&
  42        git clone -n "file://$(pwd)/src" dst >output 2>&1 &&
  43        test $(grep Clon output | wc -l) = 1
  44'
  45
  46test_expect_success 'clone does not keep pack' '
  47
  48        rm -fr dst &&
  49        git clone -n "file://$(pwd)/src" dst &&
  50        ! test -f dst/file &&
  51        ! (echo dst/.git/objects/pack/pack-* | grep "\.keep")
  52
  53'
  54
  55test_expect_success 'clone checks out files' '
  56
  57        rm -fr dst &&
  58        git clone src dst &&
  59        test -f dst/file
  60
  61'
  62
  63test_expect_success 'clone respects GIT_WORK_TREE' '
  64
  65        GIT_WORK_TREE=worktree git clone src bare &&
  66        test -f bare/config &&
  67        test -f worktree/file
  68
  69'
  70
  71test_expect_success 'clone creates intermediate directories' '
  72
  73        git clone src long/path/to/dst &&
  74        test -f long/path/to/dst/file
  75
  76'
  77
  78test_expect_success 'clone creates intermediate directories for bare repo' '
  79
  80        git clone --bare src long/path/to/bare/dst &&
  81        test -f long/path/to/bare/dst/config
  82
  83'
  84
  85test_expect_success 'clone --mirror' '
  86
  87        git clone --mirror src mirror &&
  88        test -f mirror/HEAD &&
  89        test ! -f mirror/file &&
  90        FETCH="$(cd mirror && git config remote.origin.fetch)" &&
  91        test "+refs/*:refs/*" = "$FETCH" &&
  92        MIRROR="$(cd mirror && git config --bool remote.origin.mirror)" &&
  93        test "$MIRROR" = true
  94
  95'
  96
  97test_expect_success 'clone --mirror with detached HEAD' '
  98
  99        ( cd src && git checkout HEAD^ && git rev-parse HEAD >../expected ) &&
 100        git clone --mirror src mirror.detached &&
 101        ( cd src && git checkout - ) &&
 102        GIT_DIR=mirror.detached git rev-parse HEAD >actual &&
 103        test_cmp expected actual
 104
 105'
 106
 107test_expect_success 'clone --bare with detached HEAD' '
 108
 109        ( cd src && git checkout HEAD^ && git rev-parse HEAD >../expected ) &&
 110        git clone --bare src bare.detached &&
 111        ( cd src && git checkout - ) &&
 112        GIT_DIR=bare.detached git rev-parse HEAD >actual &&
 113        test_cmp expected actual
 114
 115'
 116
 117test_expect_success 'clone --bare names the local repository <name>.git' '
 118
 119        git clone --bare src &&
 120        test -d src.git
 121
 122'
 123
 124test_expect_success 'clone --mirror does not repeat tags' '
 125
 126        (cd src &&
 127         git tag some-tag HEAD) &&
 128        git clone --mirror src mirror2 &&
 129        (cd mirror2 &&
 130         git show-ref 2> clone.err > clone.out) &&
 131        test_must_fail grep Duplicate mirror2/clone.err &&
 132        grep some-tag mirror2/clone.out
 133
 134'
 135
 136test_expect_success 'clone to destination with trailing /' '
 137
 138        git clone src target-1/ &&
 139        T=$( cd target-1 && git rev-parse HEAD ) &&
 140        S=$( cd src && git rev-parse HEAD ) &&
 141        test "$T" = "$S"
 142
 143'
 144
 145test_expect_success 'clone to destination with extra trailing /' '
 146
 147        git clone src target-2/// &&
 148        T=$( cd target-2 && git rev-parse HEAD ) &&
 149        S=$( cd src && git rev-parse HEAD ) &&
 150        test "$T" = "$S"
 151
 152'
 153
 154test_expect_success 'clone to an existing empty directory' '
 155        mkdir target-3 &&
 156        git clone src target-3 &&
 157        T=$( cd target-3 && git rev-parse HEAD ) &&
 158        S=$( cd src && git rev-parse HEAD ) &&
 159        test "$T" = "$S"
 160'
 161
 162test_expect_success 'clone to an existing non-empty directory' '
 163        mkdir target-4 &&
 164        >target-4/Fakefile &&
 165        test_must_fail git clone src target-4
 166'
 167
 168test_expect_success 'clone to an existing path' '
 169        >target-5 &&
 170        test_must_fail git clone src target-5
 171'
 172
 173test_expect_success 'clone a void' '
 174        mkdir src-0 &&
 175        (
 176                cd src-0 && git init
 177        ) &&
 178        git clone "file://$(pwd)/src-0" target-6 2>err-6 &&
 179        ! grep "fatal:" err-6 &&
 180        (
 181                cd src-0 && test_commit A
 182        ) &&
 183        git clone "file://$(pwd)/src-0" target-7 2>err-7 &&
 184        ! grep "fatal:" err-7 &&
 185        # There is no reason to insist they are bit-for-bit
 186        # identical, but this test should suffice for now.
 187        test_cmp target-6/.git/config target-7/.git/config
 188'
 189
 190test_expect_success 'clone respects global branch.autosetuprebase' '
 191        (
 192                test_config="$HOME/.gitconfig" &&
 193                git config -f "$test_config" branch.autosetuprebase remote &&
 194                rm -fr dst &&
 195                git clone src dst &&
 196                cd dst &&
 197                actual="z$(git config branch.master.rebase)" &&
 198                test ztrue = $actual
 199        )
 200'
 201
 202test_expect_success 'respect url-encoding of file://' '
 203        git init x+y &&
 204        git clone "file://$PWD/x+y" xy-url-1 &&
 205        git clone "file://$PWD/x%2By" xy-url-2
 206'
 207
 208test_expect_success 'do not query-string-decode + in URLs' '
 209        rm -rf x+y &&
 210        git init "x y" &&
 211        test_must_fail git clone "file://$PWD/x+y" xy-no-plus
 212'
 213
 214test_expect_success 'do not respect url-encoding of non-url path' '
 215        git init x+y &&
 216        test_must_fail git clone x%2By xy-regular &&
 217        git clone x+y xy-regular
 218'
 219
 220test_expect_success 'clone separate gitdir' '
 221        rm -rf dst &&
 222        git clone --separate-git-dir realgitdir src dst &&
 223        test -d realgitdir/refs
 224'
 225
 226test_expect_success 'clone separate gitdir: output' '
 227        echo "gitdir: `pwd`/realgitdir" >expected &&
 228        test_cmp expected dst/.git
 229'
 230
 231test_expect_success 'clone from .git file' '
 232        git clone dst/.git dst2
 233'
 234
 235test_expect_success 'fetch from .git gitfile' '
 236        (
 237                cd dst2 &&
 238                git fetch ../dst/.git
 239        )
 240'
 241
 242test_expect_success 'fetch from gitfile parent' '
 243        (
 244                cd dst2 &&
 245                git fetch ../dst
 246        )
 247'
 248
 249test_expect_success 'clone separate gitdir where target already exists' '
 250        rm -rf dst &&
 251        test_must_fail git clone --separate-git-dir realgitdir src dst
 252'
 253
 254test_expect_success 'clone --reference from original' '
 255        git clone --shared --bare src src-1 &&
 256        git clone --bare src src-2 &&
 257        git clone --reference=src-2 --bare src-1 target-8 &&
 258        grep /src-2/ target-8/objects/info/alternates
 259'
 260
 261test_expect_success 'clone with more than one --reference' '
 262        git clone --bare src src-3 &&
 263        git clone --bare src src-4 &&
 264        git clone --reference=src-3 --reference=src-4 src target-9 &&
 265        grep /src-3/ target-9/.git/objects/info/alternates &&
 266        grep /src-4/ target-9/.git/objects/info/alternates
 267'
 268
 269test_expect_success 'clone from original with relative alternate' '
 270        mkdir nest &&
 271        git clone --bare src nest/src-5 &&
 272        echo ../../../src/.git/objects >nest/src-5/objects/info/alternates &&
 273        git clone --bare nest/src-5 target-10 &&
 274        grep /src/\\.git/objects target-10/objects/info/alternates
 275'
 276
 277test_expect_success 'clone checking out a tag' '
 278        git clone --branch=some-tag src dst.tag &&
 279        GIT_DIR=src/.git git rev-parse some-tag >expected &&
 280        test_cmp expected dst.tag/.git/HEAD &&
 281        GIT_DIR=dst.tag/.git git config remote.origin.fetch >fetch.actual &&
 282        echo "+refs/heads/*:refs/remotes/origin/*" >fetch.expected &&
 283        test_cmp fetch.expected fetch.actual
 284'
 285
 286setup_ssh_wrapper () {
 287        test_expect_success 'setup ssh wrapper' '
 288                cp "$GIT_BUILD_DIR/test-fake-ssh$X" \
 289                        "$TRASH_DIRECTORY/ssh-wrapper$X" &&
 290                GIT_SSH="$TRASH_DIRECTORY/ssh-wrapper$X" &&
 291                export GIT_SSH &&
 292                export TRASH_DIRECTORY &&
 293                >"$TRASH_DIRECTORY"/ssh-output
 294        '
 295}
 296
 297copy_ssh_wrapper_as () {
 298        cp "$TRASH_DIRECTORY/ssh-wrapper$X" "${1%$X}$X" &&
 299        GIT_SSH="${1%$X}$X" &&
 300        export GIT_SSH
 301}
 302
 303expect_ssh () {
 304        test_when_finished '
 305                (cd "$TRASH_DIRECTORY" && rm -f ssh-expect && >ssh-output)
 306        ' &&
 307        {
 308                case "$#" in
 309                1)
 310                        ;;
 311                2)
 312                        echo "ssh: $1 git-upload-pack '$2'"
 313                        ;;
 314                3)
 315                        echo "ssh: $1 $2 git-upload-pack '$3'"
 316                        ;;
 317                *)
 318                        echo "ssh: $1 $2 git-upload-pack '$3' $4"
 319                esac
 320        } >"$TRASH_DIRECTORY/ssh-expect" &&
 321        (cd "$TRASH_DIRECTORY" && test_cmp ssh-expect ssh-output)
 322}
 323
 324setup_ssh_wrapper
 325
 326test_expect_success 'clone myhost:src uses ssh' '
 327        git clone myhost:src ssh-clone &&
 328        expect_ssh myhost src
 329'
 330
 331test_expect_success !MINGW,!CYGWIN 'clone local path foo:bar' '
 332        cp -R src "foo:bar" &&
 333        git clone "foo:bar" foobar &&
 334        expect_ssh none
 335'
 336
 337test_expect_success 'bracketed hostnames are still ssh' '
 338        git clone "[myhost:123]:src" ssh-bracket-clone &&
 339        expect_ssh "-p 123" myhost src
 340'
 341
 342test_expect_success 'uplink is not treated as putty' '
 343        copy_ssh_wrapper_as "$TRASH_DIRECTORY/uplink" &&
 344        git clone "[myhost:123]:src" ssh-bracket-clone-uplink &&
 345        expect_ssh "-p 123" myhost src
 346'
 347
 348test_expect_success 'plink is treated specially (as putty)' '
 349        copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink" &&
 350        git clone "[myhost:123]:src" ssh-bracket-clone-plink-0 &&
 351        expect_ssh "-P 123" myhost src
 352'
 353
 354test_expect_success 'plink.exe is treated specially (as putty)' '
 355        copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink.exe" &&
 356        git clone "[myhost:123]:src" ssh-bracket-clone-plink-1 &&
 357        expect_ssh "-P 123" myhost src
 358'
 359
 360test_expect_success 'tortoiseplink is like putty, with extra arguments' '
 361        copy_ssh_wrapper_as "$TRASH_DIRECTORY/tortoiseplink" &&
 362        git clone "[myhost:123]:src" ssh-bracket-clone-plink-2 &&
 363        expect_ssh "-batch -P 123" myhost src
 364'
 365
 366# Reset the GIT_SSH environment variable for clone tests.
 367setup_ssh_wrapper
 368
 369counter=0
 370# $1 url
 371# $2 none|host
 372# $3 path
 373test_clone_url () {
 374        counter=$(($counter + 1))
 375        test_might_fail git clone "$1" tmp$counter &&
 376        shift &&
 377        expect_ssh "$@"
 378}
 379
 380test_expect_success !MINGW 'clone c:temp is ssl' '
 381        test_clone_url c:temp c temp
 382'
 383
 384test_expect_success MINGW 'clone c:temp is dos drive' '
 385        test_clone_url c:temp none
 386'
 387
 388#ip v4
 389for repo in rep rep/home/project 123
 390do
 391        test_expect_success "clone host:$repo" '
 392                test_clone_url host:$repo host $repo
 393        '
 394done
 395
 396#ipv6
 397for repo in rep rep/home/project 123
 398do
 399        test_expect_success "clone [::1]:$repo" '
 400                test_clone_url [::1]:$repo ::1 "$repo"
 401        '
 402done
 403#home directory
 404test_expect_success "clone host:/~repo" '
 405        test_clone_url host:/~repo host "~repo"
 406'
 407
 408test_expect_success "clone [::1]:/~repo" '
 409        test_clone_url [::1]:/~repo ::1 "~repo"
 410'
 411
 412# Corner cases
 413for url in foo/bar:baz [foo]bar/baz:qux [foo/bar]:baz
 414do
 415        test_expect_success "clone $url is not ssh" '
 416                test_clone_url $url none
 417        '
 418done
 419
 420#with ssh:// scheme
 421#ignore trailing colon
 422for tcol in "" :
 423do
 424        test_expect_success "clone ssh://host.xz$tcol/home/user/repo" '
 425                test_clone_url "ssh://host.xz$tcol/home/user/repo" host.xz /home/user/repo
 426        '
 427        # from home directory
 428        test_expect_success "clone ssh://host.xz$tcol/~repo" '
 429        test_clone_url "ssh://host.xz$tcol/~repo" host.xz "~repo"
 430'
 431done
 432
 433# with port number
 434test_expect_success 'clone ssh://host.xz:22/home/user/repo' '
 435        test_clone_url "ssh://host.xz:22/home/user/repo" "-p 22 host.xz" "/home/user/repo"
 436'
 437
 438# from home directory with port number
 439test_expect_success 'clone ssh://host.xz:22/~repo' '
 440        test_clone_url "ssh://host.xz:22/~repo" "-p 22 host.xz" "~repo"
 441'
 442
 443#IPv6
 444for tuah in ::1 [::1] [::1]: user@::1 user@[::1] user@[::1]: [user@::1] [user@::1]:
 445do
 446        ehost=$(echo $tuah | sed -e "s/1]:/1]/ "| tr -d "[]")
 447        test_expect_success "clone ssh://$tuah/home/user/repo" "
 448          test_clone_url ssh://$tuah/home/user/repo $ehost /home/user/repo
 449        "
 450done
 451
 452#IPv6 from home directory
 453for tuah in ::1 [::1] user@::1 user@[::1] [user@::1]
 454do
 455        euah=$(echo $tuah | tr -d "[]")
 456        test_expect_success "clone ssh://$tuah/~repo" "
 457          test_clone_url ssh://$tuah/~repo $euah '~repo'
 458        "
 459done
 460
 461#IPv6 with port number
 462for tuah in [::1] user@[::1] [user@::1]
 463do
 464        euah=$(echo $tuah | tr -d "[]")
 465        test_expect_success "clone ssh://$tuah:22/home/user/repo" "
 466          test_clone_url ssh://$tuah:22/home/user/repo '-p 22' $euah /home/user/repo
 467        "
 468done
 469
 470#IPv6 from home directory with port number
 471for tuah in [::1] user@[::1] [user@::1]
 472do
 473        euah=$(echo $tuah | tr -d "[]")
 474        test_expect_success "clone ssh://$tuah:22/~repo" "
 475          test_clone_url ssh://$tuah:22/~repo '-p 22' $euah '~repo'
 476        "
 477done
 478
 479test_expect_success 'clone from a repository with two identical branches' '
 480
 481        (
 482                cd src &&
 483                git checkout -b another master
 484        ) &&
 485        git clone src target-11 &&
 486        test "z$( cd target-11 && git symbolic-ref HEAD )" = zrefs/heads/another
 487
 488'
 489
 490test_expect_success 'shallow clone locally' '
 491        git clone --depth=1 --no-local src ssrrcc &&
 492        git clone ssrrcc ddsstt &&
 493        test_cmp ssrrcc/.git/shallow ddsstt/.git/shallow &&
 494        ( cd ddsstt && git fsck )
 495'
 496
 497test_expect_success 'GIT_TRACE_PACKFILE produces a usable pack' '
 498        rm -rf dst.git &&
 499        GIT_TRACE_PACKFILE=$PWD/tmp.pack git clone --no-local --bare src dst.git &&
 500        git init --bare replay.git &&
 501        git -C replay.git index-pack -v --stdin <tmp.pack
 502'
 503
 504test_done