#!/bin/sh global test_description := 'clone' source ./test-lib.sh global X := '' test_have_prereq !MINGW || global X := '.exe' test_expect_success setup ' rm -fr .git && test_create_repo src && ( cd src && >file && git add file && git commit -m initial && echo 1 >file && git add file && git commit -m updated ) ' test_expect_success 'clone with excess parameters (1)' ' rm -fr dst && test_must_fail git clone -n src dst junk ' test_expect_success 'clone with excess parameters (2)' ' rm -fr dst && test_must_fail git clone -n "file://$(pwd)/src" dst junk ' test_expect_success C_LOCALE_OUTPUT 'output from clone' ' rm -fr dst && git clone -n "file://$(pwd)/src" dst >output 2>&1 && test $(grep Clon output | wc -l) = 1 ' test_expect_success 'clone does not keep pack' ' rm -fr dst && git clone -n "file://$(pwd)/src" dst && ! test -f dst/file && ! (echo dst/.git/objects/pack/pack-* | grep "\.keep") ' test_expect_success 'clone checks out files' ' rm -fr dst && git clone src dst && test -f dst/file ' test_expect_success 'clone respects GIT_WORK_TREE' ' GIT_WORK_TREE=worktree git clone src bare && test -f bare/config && test -f worktree/file ' test_expect_success 'clone from hooks' ' test_create_repo r0 && cd r0 && test_commit initial && cd .. && git init r1 && cd r1 && cat >.git/hooks/pre-commit <<-\EOF && #!/bin/sh git clone ../r0 ../r2 exit 1 EOF chmod u+x .git/hooks/pre-commit && : >file && git add file && test_must_fail git commit -m invoke-hook && cd .. && test_cmp r0/.git/HEAD r2/.git/HEAD && test_cmp r0/initial.t r2/initial.t ' test_expect_success 'clone creates intermediate directories' ' git clone src long/path/to/dst && test -f long/path/to/dst/file ' test_expect_success 'clone creates intermediate directories for bare repo' ' git clone --bare src long/path/to/bare/dst && test -f long/path/to/bare/dst/config ' test_expect_success 'clone --mirror' ' git clone --mirror src mirror && test -f mirror/HEAD && test ! -f mirror/file && FETCH="$(cd mirror && git config remote.origin.fetch)" && test "+refs/*:refs/*" = "$FETCH" && MIRROR="$(cd mirror && git config --bool remote.origin.mirror)" && test "$MIRROR" = true ' test_expect_success 'clone --mirror with detached HEAD' ' ( cd src && git checkout HEAD^ && git rev-parse HEAD >../expected ) && git clone --mirror src mirror.detached && ( cd src && git checkout - ) && GIT_DIR=mirror.detached git rev-parse HEAD >actual && test_cmp expected actual ' test_expect_success 'clone --bare with detached HEAD' ' ( cd src && git checkout HEAD^ && git rev-parse HEAD >../expected ) && git clone --bare src bare.detached && ( cd src && git checkout - ) && GIT_DIR=bare.detached git rev-parse HEAD >actual && test_cmp expected actual ' test_expect_success 'clone --bare names the local repository .git' ' git clone --bare src && test -d src.git ' test_expect_success 'clone --mirror does not repeat tags' ' (cd src && git tag some-tag HEAD) && git clone --mirror src mirror2 && (cd mirror2 && git show-ref 2> clone.err > clone.out) && test_must_fail grep Duplicate mirror2/clone.err && grep some-tag mirror2/clone.out ' test_expect_success 'clone to destination with trailing /' ' git clone src target-1/ && T=$( cd target-1 && git rev-parse HEAD ) && S=$( cd src && git rev-parse HEAD ) && test "$T" = "$S" ' test_expect_success 'clone to destination with extra trailing /' ' git clone src target-2/// && T=$( cd target-2 && git rev-parse HEAD ) && S=$( cd src && git rev-parse HEAD ) && test "$T" = "$S" ' test_expect_success 'clone to an existing empty directory' ' mkdir target-3 && git clone src target-3 && T=$( cd target-3 && git rev-parse HEAD ) && S=$( cd src && git rev-parse HEAD ) && test "$T" = "$S" ' test_expect_success 'clone to an existing non-empty directory' ' mkdir target-4 && >target-4/Fakefile && test_must_fail git clone src target-4 ' test_expect_success 'clone to an existing path' ' >target-5 && test_must_fail git clone src target-5 ' test_expect_success 'clone a void' ' mkdir src-0 && ( cd src-0 && git init ) && git clone "file://$(pwd)/src-0" target-6 2>err-6 && ! grep "fatal:" err-6 && ( cd src-0 && test_commit A ) && git clone "file://$(pwd)/src-0" target-7 2>err-7 && ! grep "fatal:" err-7 && # There is no reason to insist they are bit-for-bit # identical, but this test should suffice for now. test_cmp target-6/.git/config target-7/.git/config ' test_expect_success 'clone respects global branch.autosetuprebase' ' ( test_config="$HOME/.gitconfig" && git config -f "$test_config" branch.autosetuprebase remote && rm -fr dst && git clone src dst && cd dst && actual="z$(git config branch.master.rebase)" && test ztrue = $actual ) ' test_expect_success 'respect url-encoding of file://' ' git init x+y && git clone "file://$PWD/x+y" xy-url-1 && git clone "file://$PWD/x%2By" xy-url-2 ' test_expect_success 'do not query-string-decode + in URLs' ' rm -rf x+y && git init "x y" && test_must_fail git clone "file://$PWD/x+y" xy-no-plus ' test_expect_success 'do not respect url-encoding of non-url path' ' git init x+y && test_must_fail git clone x%2By xy-regular && git clone x+y xy-regular ' test_expect_success 'clone separate gitdir' ' rm -rf dst && git clone --separate-git-dir realgitdir src dst && test -d realgitdir/refs ' test_expect_success 'clone separate gitdir: output' ' echo "gitdir: $(pwd)/realgitdir" >expected && test_cmp expected dst/.git ' test_expect_success 'clone from .git file' ' git clone dst/.git dst2 ' test_expect_success 'fetch from .git gitfile' ' ( cd dst2 && git fetch ../dst/.git ) ' test_expect_success 'fetch from gitfile parent' ' ( cd dst2 && git fetch ../dst ) ' test_expect_success 'clone separate gitdir where target already exists' ' rm -rf dst && test_must_fail git clone --separate-git-dir realgitdir src dst ' test_expect_success 'clone --reference from original' ' git clone --shared --bare src src-1 && git clone --bare src src-2 && git clone --reference=src-2 --bare src-1 target-8 && grep /src-2/ target-8/objects/info/alternates ' test_expect_success 'clone with more than one --reference' ' git clone --bare src src-3 && git clone --bare src src-4 && git clone --reference=src-3 --reference=src-4 src target-9 && grep /src-3/ target-9/.git/objects/info/alternates && grep /src-4/ target-9/.git/objects/info/alternates ' test_expect_success 'clone from original with relative alternate' ' mkdir nest && git clone --bare src nest/src-5 && echo ../../../src/.git/objects >nest/src-5/objects/info/alternates && git clone --bare nest/src-5 target-10 && grep /src/\\.git/objects target-10/objects/info/alternates ' test_expect_success 'clone checking out a tag' ' git clone --branch=some-tag src dst.tag && GIT_DIR=src/.git git rev-parse some-tag >expected && test_cmp expected dst.tag/.git/HEAD && GIT_DIR=dst.tag/.git git config remote.origin.fetch >fetch.actual && echo "+refs/heads/*:refs/remotes/origin/*" >fetch.expected && test_cmp fetch.expected fetch.actual ' proc setup_ssh_wrapper { test_expect_success 'setup ssh wrapper' ' cp "$GIT_BUILD_DIR/t/helper/test-fake-ssh$X" \ "$TRASH_DIRECTORY/ssh-wrapper$X" && GIT_SSH="$TRASH_DIRECTORY/ssh-wrapper$X" && export GIT_SSH && export TRASH_DIRECTORY && >"$TRASH_DIRECTORY"/ssh-output ' } proc copy_ssh_wrapper_as { cp "$TRASH_DIRECTORY/ssh-wrapper$X" "$(1%$X)$X" && global GIT_SSH := ""$(1%$X)$X"" && export GIT_SSH } proc expect_ssh { test_when_finished ' (cd "$TRASH_DIRECTORY" && rm -f ssh-expect && >ssh-output) ' && do { matchstr "$Argc" { 1 { } 2 { echo "ssh: $1 git-upload-pack '$2'" } 3 { echo "ssh: $1 $2 git-upload-pack '$3'" } * { echo "ssh: $1 $2 git-upload-pack '$3' $4" } } } >"$TRASH_DIRECTORY/ssh-expect" && shell {cd $TRASH_DIRECTORY && test_cmp ssh-expect ssh-output} } setup_ssh_wrapper test_expect_success 'clone myhost:src uses ssh' ' git clone myhost:src ssh-clone && expect_ssh myhost src ' test_expect_success !MINGW,!CYGWIN 'clone local path foo:bar' ' cp -R src "foo:bar" && git clone "foo:bar" foobar && expect_ssh none ' test_expect_success 'bracketed hostnames are still ssh' ' git clone "[myhost:123]:src" ssh-bracket-clone && expect_ssh "-p 123" myhost src ' test_expect_success 'uplink is not treated as putty' ' copy_ssh_wrapper_as "$TRASH_DIRECTORY/uplink" && git clone "[myhost:123]:src" ssh-bracket-clone-uplink && expect_ssh "-p 123" myhost src ' test_expect_success 'plink is treated specially (as putty)' ' copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink" && git clone "[myhost:123]:src" ssh-bracket-clone-plink-0 && expect_ssh "-P 123" myhost src ' test_expect_success 'plink.exe is treated specially (as putty)' ' copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink.exe" && git clone "[myhost:123]:src" ssh-bracket-clone-plink-1 && expect_ssh "-P 123" myhost src ' test_expect_success 'tortoiseplink is like putty, with extra arguments' ' copy_ssh_wrapper_as "$TRASH_DIRECTORY/tortoiseplink" && git clone "[myhost:123]:src" ssh-bracket-clone-plink-2 && expect_ssh "-batch -P 123" myhost src ' # Reset the GIT_SSH environment variable for clone tests. setup_ssh_wrapper global counter := '0' # $1 url # $2 none|host # $3 path proc test_clone_url { global counter := $($counter + 1) test_might_fail git clone $1 tmp$counter && shift && expect_ssh @Argv } test_expect_success !MINGW 'clone c:temp is ssl' ' test_clone_url c:temp c temp ' test_expect_success MINGW 'clone c:temp is dos drive' ' test_clone_url c:temp none ' #ip v4 for repo in [rep rep/home/project 123] { test_expect_success "clone host:$repo" ' test_clone_url host:$repo host $repo ' } #ipv6 for repo in [rep rep/home/project 123] { test_expect_success "clone [::1]:$repo" ' test_clone_url [::1]:$repo ::1 "$repo" ' } #home directory test_expect_success "clone host:/~repo" ' test_clone_url host:/~repo host "~repo" ' test_expect_success "clone [::1]:/~repo" ' test_clone_url [::1]:/~repo ::1 "~repo" ' # Corner cases for url in [foo/bar:baz [foo]bar/baz:qux [foo/bar]:baz] { test_expect_success "clone $url is not ssh" ' test_clone_url $url none ' } #with ssh:// scheme #ignore trailing colon for tcol in ["" :] { test_expect_success "clone ssh://host.xz$tcol/home/user/repo" ' test_clone_url "ssh://host.xz$tcol/home/user/repo" host.xz /home/user/repo ' # from home directory test_expect_success "clone ssh://host.xz$tcol/~repo" ' test_clone_url "ssh://host.xz$tcol/~repo" host.xz "~repo" ' } # with port number test_expect_success 'clone ssh://host.xz:22/home/user/repo' ' test_clone_url "ssh://host.xz:22/home/user/repo" "-p 22 host.xz" "/home/user/repo" ' # from home directory with port number test_expect_success 'clone ssh://host.xz:22/~repo' ' test_clone_url "ssh://host.xz:22/~repo" "-p 22 host.xz" "~repo" ' #IPv6 for tuah in [::1 [::1] [::1]: user@::1 user@[::1] user@[::1]: [user@::1] [user@::1]:] { global ehost := $[echo $tuah | sed -e "s/1]:/1]/" | tr -d "[]] test_expect_success "clone ssh://$tuah/home/user/repo" " test_clone_url ssh://$tuah/home/user/repo $ehost /home/user/repo " } #IPv6 from home directory for tuah in [::1 [::1] user@::1 user@[::1] [user@::1]] { global euah := $[echo $tuah | tr -d "[]] test_expect_success "clone ssh://$tuah/~repo" " test_clone_url ssh://$tuah/~repo $euah '~repo' " } #IPv6 with port number for tuah in [[::1] user@[::1] [user@::1]] { global euah := $[echo $tuah | tr -d "[]] test_expect_success "clone ssh://$tuah:22/home/user/repo" " test_clone_url ssh://$tuah:22/home/user/repo '-p 22' $euah /home/user/repo " } #IPv6 from home directory with port number for tuah in [[::1] user@[::1] [user@::1]] { global euah := $[echo $tuah | tr -d "[]] test_expect_success "clone ssh://$tuah:22/~repo" " test_clone_url ssh://$tuah:22/~repo '-p 22' $euah '~repo' " } test_expect_success 'clone from a repository with two identical branches' ' ( cd src && git checkout -b another master ) && git clone src target-11 && test "z$( cd target-11 && git symbolic-ref HEAD )" = zrefs/heads/another ' test_expect_success 'shallow clone locally' ' git clone --depth=1 --no-local src ssrrcc && git clone ssrrcc ddsstt && test_cmp ssrrcc/.git/shallow ddsstt/.git/shallow && ( cd ddsstt && git fsck ) ' test_expect_success 'GIT_TRACE_PACKFILE produces a usable pack' ' rm -rf dst.git && GIT_TRACE_PACKFILE=$PWD/tmp.pack git clone --no-local --bare src dst.git && git init --bare replay.git && git -C replay.git index-pack -v --stdin <"\n"> <"\trm -fr .git &&\n"> <"\ttest_create_repo src &&\n"> <"\t(\n"> <"\t\tcd src &&\n"> <"\t\t>file &&\n"> <"\t\tgit add file &&\n"> <"\t\tgit commit -m initial &&\n"> <"\t\techo 1 >file &&\n"> <"\t\tgit add file &&\n"> <"\t\tgit commit -m updated\n"> <"\t)\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"clone with excess parameters (1)">)} { (SQ <"\n"> <"\n"> <"\trm -fr dst &&\n"> <"\ttest_must_fail git clone -n src dst junk\n"> <"\n">) } ) (C {(test_expect_success)} {(SQ <"clone with excess parameters (2)">)} { (SQ <"\n"> <"\n"> <"\trm -fr dst &&\n"> <"\ttest_must_fail git clone -n \"file://$(pwd)/src\" dst junk\n"> <"\n"> ) } ) (C {(test_expect_success)} {(C_LOCALE_OUTPUT)} {(SQ <"output from clone">)} { (SQ <"\n"> <"\trm -fr dst &&\n"> <"\tgit clone -n \"file://$(pwd)/src\" dst >output 2>&1 &&\n"> <"\ttest $(grep Clon output | wc -l) = 1\n"> ) } ) (C {(test_expect_success)} {(SQ <"clone does not keep pack">)} { (SQ <"\n"> <"\n"> <"\trm -fr dst &&\n"> <"\tgit clone -n \"file://$(pwd)/src\" dst &&\n"> <"\t! test -f dst/file &&\n"> <"\t! (echo dst/.git/objects/pack/pack-* | grep \"\\.keep\")\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"clone checks out files">)} { (SQ <"\n"> <"\n"> <"\trm -fr dst &&\n"> <"\tgit clone src dst &&\n"> <"\ttest -f dst/file\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"clone respects GIT_WORK_TREE">)} { (SQ <"\n"> <"\n"> <"\tGIT_WORK_TREE=worktree git clone src bare &&\n"> <"\ttest -f bare/config &&\n"> <"\ttest -f worktree/file\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"clone from hooks">)} { (SQ <"\n"> <"\n"> <"\ttest_create_repo r0 &&\n"> <"\tcd r0 &&\n"> <"\ttest_commit initial &&\n"> <"\tcd .. &&\n"> <"\tgit init r1 &&\n"> <"\tcd r1 &&\n"> <"\tcat >.git/hooks/pre-commit <<-\\EOF &&\n"> <"\t#!/bin/sh\n"> <"\tgit clone ../r0 ../r2\n"> <"\texit 1\n"> <"\tEOF\n"> <"\tchmod u+x .git/hooks/pre-commit &&\n"> <"\t: >file &&\n"> <"\tgit add file &&\n"> <"\ttest_must_fail git commit -m invoke-hook &&\n"> <"\tcd .. &&\n"> <"\ttest_cmp r0/.git/HEAD r2/.git/HEAD &&\n"> <"\ttest_cmp r0/initial.t r2/initial.t\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"clone creates intermediate directories">)} { (SQ <"\n"> <"\n"> <"\tgit clone src long/path/to/dst &&\n"> <"\ttest -f long/path/to/dst/file\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"clone creates intermediate directories for bare repo">)} { (SQ <"\n"> <"\n"> <"\tgit clone --bare src long/path/to/bare/dst &&\n"> <"\ttest -f long/path/to/bare/dst/config\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"clone --mirror">)} { (SQ <"\n"> <"\n"> <"\tgit clone --mirror src mirror &&\n"> <"\ttest -f mirror/HEAD &&\n"> <"\ttest ! -f mirror/file &&\n"> <"\tFETCH=\"$(cd mirror && git config remote.origin.fetch)\" &&\n"> <"\ttest \"+refs/*:refs/*\" = \"$FETCH\" &&\n"> <"\tMIRROR=\"$(cd mirror && git config --bool remote.origin.mirror)\" &&\n"> <"\ttest \"$MIRROR\" = true\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"clone --mirror with detached HEAD">)} { (SQ <"\n"> <"\n"> <"\t( cd src && git checkout HEAD^ && git rev-parse HEAD >../expected ) &&\n"> <"\tgit clone --mirror src mirror.detached &&\n"> <"\t( cd src && git checkout - ) &&\n"> <"\tGIT_DIR=mirror.detached git rev-parse HEAD >actual &&\n"> <"\ttest_cmp expected actual\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"clone --bare with detached HEAD">)} { (SQ <"\n"> <"\n"> <"\t( cd src && git checkout HEAD^ && git rev-parse HEAD >../expected ) &&\n"> <"\tgit clone --bare src bare.detached &&\n"> <"\t( cd src && git checkout - ) &&\n"> <"\tGIT_DIR=bare.detached git rev-parse HEAD >actual &&\n"> <"\ttest_cmp expected actual\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"clone --bare names the local repository .git">)} {(SQ <"\n"> <"\n"> <"\tgit clone --bare src &&\n"> <"\ttest -d src.git\n"> <"\n">)} ) (C {(test_expect_success)} {(SQ <"clone --mirror does not repeat tags">)} { (SQ <"\n"> <"\n"> <"\t(cd src &&\n"> <"\t git tag some-tag HEAD) &&\n"> <"\tgit clone --mirror src mirror2 &&\n"> <"\t(cd mirror2 &&\n"> <"\t git show-ref 2> clone.err > clone.out) &&\n"> <"\ttest_must_fail grep Duplicate mirror2/clone.err &&\n"> <"\tgrep some-tag mirror2/clone.out\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"clone to destination with trailing /">)} { (SQ <"\n"> <"\n"> <"\tgit clone src target-1/ &&\n"> <"\tT=$( cd target-1 && git rev-parse HEAD ) &&\n"> <"\tS=$( cd src && git rev-parse HEAD ) &&\n"> <"\ttest \"$T\" = \"$S\"\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"clone to destination with extra trailing /">)} { (SQ <"\n"> <"\n"> <"\tgit clone src target-2/// &&\n"> <"\tT=$( cd target-2 && git rev-parse HEAD ) &&\n"> <"\tS=$( cd src && git rev-parse HEAD ) &&\n"> <"\ttest \"$T\" = \"$S\"\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"clone to an existing empty directory">)} { (SQ <"\n"> <"\tmkdir target-3 &&\n"> <"\tgit clone src target-3 &&\n"> <"\tT=$( cd target-3 && git rev-parse HEAD ) &&\n"> <"\tS=$( cd src && git rev-parse HEAD ) &&\n"> <"\ttest \"$T\" = \"$S\"\n"> ) } ) (C {(test_expect_success)} {(SQ <"clone to an existing non-empty directory">)} { (SQ <"\n"> <"\tmkdir target-4 &&\n"> <"\t>target-4/Fakefile &&\n"> <"\ttest_must_fail git clone src target-4\n"> ) } ) (C {(test_expect_success)} {(SQ <"clone to an existing path">)} {(SQ <"\n"> <"\t>target-5 &&\n"> <"\ttest_must_fail git clone src target-5\n">)} ) (C {(test_expect_success)} {(SQ <"clone a void">)} { (SQ <"\n"> <"\tmkdir src-0 &&\n"> <"\t(\n"> <"\t\tcd src-0 && git init\n"> <"\t) &&\n"> <"\tgit clone \"file://$(pwd)/src-0\" target-6 2>err-6 &&\n"> <"\t! grep \"fatal:\" err-6 &&\n"> <"\t(\n"> <"\t\tcd src-0 && test_commit A\n"> <"\t) &&\n"> <"\tgit clone \"file://$(pwd)/src-0\" target-7 2>err-7 &&\n"> <"\t! grep \"fatal:\" err-7 &&\n"> <"\t# There is no reason to insist they are bit-for-bit\n"> <"\t# identical, but this test should suffice for now.\n"> <"\ttest_cmp target-6/.git/config target-7/.git/config\n"> ) } ) (C {(test_expect_success)} {(SQ <"clone respects global branch.autosetuprebase">)} { (SQ <"\n"> <"\t(\n"> <"\t\ttest_config=\"$HOME/.gitconfig\" &&\n"> <"\t\tgit config -f \"$test_config\" branch.autosetuprebase remote &&\n"> <"\t\trm -fr dst &&\n"> <"\t\tgit clone src dst &&\n"> <"\t\tcd dst &&\n"> <"\t\tactual=\"z$(git config branch.master.rebase)\" &&\n"> <"\t\ttest ztrue = $actual\n"> <"\t)\n"> ) } ) (C {(test_expect_success)} {(SQ <"respect url-encoding of file://">)} { (SQ <"\n"> <"\tgit init x+y &&\n"> <"\tgit clone \"file://$PWD/x+y\" xy-url-1 &&\n"> <"\tgit clone \"file://$PWD/x%2By\" xy-url-2\n"> ) } ) (C {(test_expect_success)} {(SQ <"do not query-string-decode + in URLs">)} { (SQ <"\n"> <"\trm -rf x+y &&\n"> <"\tgit init \"x y\" &&\n"> <"\ttest_must_fail git clone \"file://$PWD/x+y\" xy-no-plus\n"> ) } ) (C {(test_expect_success)} {(SQ <"do not respect url-encoding of non-url path">)} { (SQ <"\n"> <"\tgit init x+y &&\n"> <"\ttest_must_fail git clone x%2By xy-regular &&\n"> <"\tgit clone x+y xy-regular\n"> ) } ) (C {(test_expect_success)} {(SQ <"clone separate gitdir">)} { (SQ <"\n"> <"\trm -rf dst &&\n"> <"\tgit clone --separate-git-dir realgitdir src dst &&\n"> <"\ttest -d realgitdir/refs\n"> ) } ) (C {(test_expect_success)} {(SQ <"clone separate gitdir: output">)} { (SQ <"\n"> <"\techo \"gitdir: $(pwd)/realgitdir\" >expected &&\n"> <"\ttest_cmp expected dst/.git\n"> ) } ) (C {(test_expect_success)} {(SQ <"clone from .git file">)} {(SQ <"\n"> <"\tgit clone dst/.git dst2\n">)} ) (C {(test_expect_success)} {(SQ <"fetch from .git gitfile">)} {(SQ <"\n"> <"\t(\n"> <"\t\tcd dst2 &&\n"> <"\t\tgit fetch ../dst/.git\n"> <"\t)\n">)} ) (C {(test_expect_success)} {(SQ <"fetch from gitfile parent">)} {(SQ <"\n"> <"\t(\n"> <"\t\tcd dst2 &&\n"> <"\t\tgit fetch ../dst\n"> <"\t)\n">)} ) (C {(test_expect_success)} {(SQ <"clone separate gitdir where target already exists">)} { (SQ <"\n"> <"\trm -rf dst &&\n"> <"\ttest_must_fail git clone --separate-git-dir realgitdir src dst\n"> ) } ) (C {(test_expect_success)} {(SQ <"clone --reference from original">)} { (SQ <"\n"> <"\tgit clone --shared --bare src src-1 &&\n"> <"\tgit clone --bare src src-2 &&\n"> <"\tgit clone --reference=src-2 --bare src-1 target-8 &&\n"> <"\tgrep /src-2/ target-8/objects/info/alternates\n"> ) } ) (C {(test_expect_success)} {(SQ <"clone with more than one --reference">)} { (SQ <"\n"> <"\tgit clone --bare src src-3 &&\n"> <"\tgit clone --bare src src-4 &&\n"> <"\tgit clone --reference=src-3 --reference=src-4 src target-9 &&\n"> <"\tgrep /src-3/ target-9/.git/objects/info/alternates &&\n"> <"\tgrep /src-4/ target-9/.git/objects/info/alternates\n"> ) } ) (C {(test_expect_success)} {(SQ <"clone from original with relative alternate">)} { (SQ <"\n"> <"\tmkdir nest &&\n"> <"\tgit clone --bare src nest/src-5 &&\n"> <"\techo ../../../src/.git/objects >nest/src-5/objects/info/alternates &&\n"> <"\tgit clone --bare nest/src-5 target-10 &&\n"> <"\tgrep /src/\\\\.git/objects target-10/objects/info/alternates\n"> ) } ) (C {(test_expect_success)} {(SQ <"clone checking out a tag">)} { (SQ <"\n"> <"\tgit clone --branch=some-tag src dst.tag &&\n"> <"\tGIT_DIR=src/.git git rev-parse some-tag >expected &&\n"> <"\ttest_cmp expected dst.tag/.git/HEAD &&\n"> <"\tGIT_DIR=dst.tag/.git git config remote.origin.fetch >fetch.actual &&\n"> <"\techo \"+refs/heads/*:refs/remotes/origin/*\" >fetch.expected &&\n"> <"\ttest_cmp fetch.expected fetch.actual\n"> ) } ) (FuncDef name: setup_ssh_wrapper body: (BraceGroup children: [ (C {(test_expect_success)} {(SQ <"setup ssh wrapper">)} { (SQ <"\n"> <"\t\tcp \"$GIT_BUILD_DIR/t/helper/test-fake-ssh$X\" \\\n"> <"\t\t\t\"$TRASH_DIRECTORY/ssh-wrapper$X\" &&\n"> <"\t\tGIT_SSH=\"$TRASH_DIRECTORY/ssh-wrapper$X\" &&\n"> <"\t\texport GIT_SSH &&\n"> <"\t\texport TRASH_DIRECTORY &&\n"> <"\t\t>\"$TRASH_DIRECTORY\"/ssh-output\n"> <"\t"> ) } ) ] spids: [610] ) spids: [605 609] ) (FuncDef name: copy_ssh_wrapper_as body: (BraceGroup children: [ (AndOr children: [ (C {(cp)} {(DQ ($ VSub_Name "$TRASH_DIRECTORY") (/ssh-wrapper) ($ VSub_Name "$X"))} { (DQ (BracedVarSub token: suffix_op: (StringUnary op_id:VOp1_Percent arg_word:{($ VSub_Name "$X")}) spids: [650 654] ) ($ VSub_Name "$X") ) } ) (AndOr children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:GIT_SSH) op: Equal rhs: { (DQ (BracedVarSub token: suffix_op: (StringUnary op_id: VOp1_Percent arg_word: {($ VSub_Name "$X")} ) spids: [663 667] ) ($ VSub_Name "$X") ) } spids: [661] ) ] spids: [661] ) (C {(export)} {(GIT_SSH)}) ] op_id: Op_DAmp ) ] op_id: Op_DAmp ) ] spids: [638] ) spids: [633 637] ) (FuncDef name: expect_ssh body: (BraceGroup children: [ (AndOr children: [ (C {(test_when_finished)} { (SQ <"\n"> <"\t\t(cd \"$TRASH_DIRECTORY\" && rm -f ssh-expect && >ssh-output)\n"> <"\t"> ) } ) (AndOr children: [ (BraceGroup children: [ (Case to_match: {(DQ ($ VSub_Pound "$#"))} arms: [ (case_arm pat_list: [{(1)}] spids: [712 713 716 -1] ) (case_arm pat_list: [{(2)}] action: [ (C {(echo)} { (DQ ("ssh: ") ($ VSub_Number "$1") (" git-upload-pack '") ($ VSub_Number "$2") ("'") ) } ) ] spids: [719 720 734 -1] ) (case_arm pat_list: [{(3)}] action: [ (C {(echo)} { (DQ ("ssh: ") ($ VSub_Number "$1") (" ") ($ VSub_Number "$2") (" git-upload-pack '") ($ VSub_Number "$3") ("'") ) } ) ] spids: [737 738 754 -1] ) (case_arm pat_list: [{(Lit_Other "*")}] action: [ (C {(echo)} { (DQ ("ssh: ") ($ VSub_Number "$1") (" ") ($ VSub_Number "$2") (" git-upload-pack '") ($ VSub_Number "$3") ("' ") ($ VSub_Number "$4") ) } ) ] spids: [757 758 -1 775] ) ] spids: [703 709 775] ) ] redirects: [ (Redir op_id: Redir_Great fd: -1 arg_word: {(DQ ($ VSub_Name "$TRASH_DIRECTORY") (/ssh-expect))} spids: [780] ) ] spids: [700] ) (Subshell child: (AndOr children: [ (C {(cd)} {(DQ ($ VSub_Name "$TRASH_DIRECTORY"))}) (C {(test_cmp)} {(ssh-expect)} {(ssh-output)}) ] op_id: Op_DAmp ) spids: [789 803] ) ] op_id: Op_DAmp ) ] op_id: Op_DAmp ) ] spids: [686] ) spids: [681 685] ) (C {(setup_ssh_wrapper)}) (C {(test_expect_success)} {(SQ <"clone myhost:src uses ssh">)} {(SQ <"\n"> <"\tgit clone myhost:src ssh-clone &&\n"> <"\texpect_ssh myhost src\n">)} ) (C {(test_expect_success)} {(KW_Bang "!") (MINGW) (Lit_Comma ",") (KW_Bang "!") (CYGWIN)} {(SQ <"clone local path foo:bar">)} { (SQ <"\n"> <"\tcp -R src \"foo:bar\" &&\n"> <"\tgit clone \"foo:bar\" foobar &&\n"> <"\texpect_ssh none\n"> ) } ) (C {(test_expect_success)} {(SQ <"bracketed hostnames are still ssh">)} { (SQ <"\n"> <"\tgit clone \"[myhost:123]:src\" ssh-bracket-clone &&\n"> <"\texpect_ssh \"-p 123\" myhost src\n"> ) } ) (C {(test_expect_success)} {(SQ <"uplink is not treated as putty">)} { (SQ <"\n"> <"\tcopy_ssh_wrapper_as \"$TRASH_DIRECTORY/uplink\" &&\n"> <"\tgit clone \"[myhost:123]:src\" ssh-bracket-clone-uplink &&\n"> <"\texpect_ssh \"-p 123\" myhost src\n"> ) } ) (C {(test_expect_success)} {(SQ <"plink is treated specially (as putty)">)} { (SQ <"\n"> <"\tcopy_ssh_wrapper_as \"$TRASH_DIRECTORY/plink\" &&\n"> <"\tgit clone \"[myhost:123]:src\" ssh-bracket-clone-plink-0 &&\n"> <"\texpect_ssh \"-P 123\" myhost src\n"> ) } ) (C {(test_expect_success)} {(SQ <"plink.exe is treated specially (as putty)">)} { (SQ <"\n"> <"\tcopy_ssh_wrapper_as \"$TRASH_DIRECTORY/plink.exe\" &&\n"> <"\tgit clone \"[myhost:123]:src\" ssh-bracket-clone-plink-1 &&\n"> <"\texpect_ssh \"-P 123\" myhost src\n"> ) } ) (C {(test_expect_success)} {(SQ <"tortoiseplink is like putty, with extra arguments">)} { (SQ <"\n"> <"\tcopy_ssh_wrapper_as \"$TRASH_DIRECTORY/tortoiseplink\" &&\n"> <"\tgit clone \"[myhost:123]:src\" ssh-bracket-clone-plink-2 &&\n"> <"\texpect_ssh \"-batch -P 123\" myhost src\n"> ) } ) (C {(setup_ssh_wrapper)}) (Assignment keyword: Assign_None pairs: [(assign_pair lhs:(LhsName name:counter) op:Equal rhs:{(0)} spids:[919])] spids: [919] ) (FuncDef name: test_clone_url body: (BraceGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:counter) op: Equal rhs: { (ArithSubPart anode: (ArithBinary op_id: Arith_Plus left: (ArithWord w:{($ VSub_Name "$counter")}) right: (ArithWord w:{(Lit_Digits 1)}) ) spids: [940 947] ) } spids: [939] ) ] spids: [939] ) (AndOr children: [ (C {(test_might_fail)} {(git)} {(clone)} {(DQ ($ VSub_Number "$1"))} {(tmp) ($ VSub_Name "$counter")} ) (AndOr children: [(C {(shift)}) (C {(expect_ssh)} {(DQ ($ VSub_At "$@"))})] op_id: Op_DAmp ) ] op_id: Op_DAmp ) ] spids: [936] ) spids: [931 935] ) (C {(test_expect_success)} {(KW_Bang "!") (MINGW)} {(SQ <"clone c:temp is ssl">)} {(SQ <"\n"> <"\ttest_clone_url c:temp c temp\n">)} ) (C {(test_expect_success)} {(MINGW)} {(SQ <"clone c:temp is dos drive">)} {(SQ <"\n"> <"\ttest_clone_url c:temp none\n">)} ) (ForEach iter_name: repo iter_words: [{(rep)} {(rep/home/project)} {(123)}] do_arg_iter: False body: (DoGroup children: [ (C {(test_expect_success)} {(DQ ("clone host:") ($ VSub_Name "$repo"))} {(SQ <"\n"> <"\t\ttest_clone_url host:$repo host $repo\n"> <"\t">)} ) ] spids: [1024 1040] ) spids: [1017 -1] ) (ForEach iter_name: repo iter_words: [{(rep)} {(rep/home/project)} {(123)}] do_arg_iter: False body: (DoGroup children: [ (C {(test_expect_success)} {(DQ ("clone [::1]:") ($ VSub_Name "$repo"))} {(SQ <"\n"> <"\t\ttest_clone_url [::1]:$repo ::1 \"$repo\"\n"> <"\t">)} ) ] spids: [1058 1074] ) spids: [1051 -1] ) (C {(test_expect_success)} {(DQ ("clone host:/~repo"))} {(SQ <"\n"> <"\ttest_clone_url host:/~repo host \"~repo\"\n">)} ) (C {(test_expect_success)} {(DQ ("clone [::1]:/~repo"))} {(SQ <"\n"> <"\ttest_clone_url [::1]:/~repo ::1 \"~repo\"\n">)} ) (ForEach iter_name: url iter_words: [ {(foo/bar) (Lit_Other ":") (baz)} {(Lit_Other "[") (foo) (Lit_Other "]") (bar/baz) (Lit_Other ":") (qux)} {(Lit_Other "[") (foo/bar) (Lit_Other "]") (Lit_Other ":") (baz)} ] do_arg_iter: False body: (DoGroup children: [ (C {(test_expect_success)} {(DQ ("clone ") ($ VSub_Name "$url") (" is not ssh"))} {(SQ <"\n"> <"\t\ttest_clone_url $url none\n"> <"\t">)} ) ] spids: [1129 1146] ) spids: [1111 -1] ) (ForEach iter_name: tcol iter_words: [{(DQ )} {(Lit_Other ":")}] do_arg_iter: False body: (DoGroup children: [ (C {(test_expect_success)} {(DQ ("clone ssh://host.xz") ($ VSub_Name "$tcol") (/home/user/repo))} { (SQ <"\n"> < "\t\ttest_clone_url \"ssh://host.xz$tcol/home/user/repo\" host.xz /home/user/repo\n" > <"\t"> ) } ) (C {(test_expect_success)} {(DQ ("clone ssh://host.xz") ($ VSub_Name "$tcol") ("/~repo"))} {(SQ <"\n"> <"\ttest_clone_url \"ssh://host.xz$tcol/~repo\" host.xz \"~repo\"\n">)} ) ] spids: [1166 1201] ) spids: [1160 -1] ) (C {(test_expect_success)} {(SQ <"clone ssh://host.xz:22/home/user/repo">)} { (SQ <"\n"> < "\ttest_clone_url \"ssh://host.xz:22/home/user/repo\" \"-p 22 host.xz\" \"/home/user/repo\"\n" > ) } ) (C {(test_expect_success)} {(SQ <"clone ssh://host.xz:22/~repo">)} {(SQ <"\n"> <"\ttest_clone_url \"ssh://host.xz:22/~repo\" \"-p 22 host.xz\" \"~repo\"\n">)} ) (ForEach iter_name: tuah iter_words: [ {(Lit_Other ":") (Lit_Other ":") (1)} {(Lit_Other "[") (Lit_Other ":") (Lit_Other ":") (1) (Lit_Other "]")} {(Lit_Other "[") (Lit_Other ":") (Lit_Other ":") (1) (Lit_Other "]") (Lit_Other ":")} {(user) (Lit_Other "@") (Lit_Other ":") (Lit_Other ":") (1)} {(user) (Lit_Other "@") (Lit_Other "[") (Lit_Other ":") (Lit_Other ":") (1) (Lit_Other "]")} {(user) (Lit_Other "@") (Lit_Other "[") (Lit_Other ":") (Lit_Other ":") (1) (Lit_Other "]") (Lit_Other ":") } {(Lit_Other "[") (user) (Lit_Other "@") (Lit_Other ":") (Lit_Other ":") (1) (Lit_Other "]")} {(Lit_Other "[") (user) (Lit_Other "@") (Lit_Other ":") (Lit_Other ":") (1) (Lit_Other "]") (Lit_Other ":") } ] do_arg_iter: False body: (DoGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:ehost) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(echo)} {($ VSub_Name "$tuah")}) (C {(sed)} {(-e)} {(DQ ("s/1]:/1]/"))}) (C {(tr)} {(-d)} {(DQ ("[]"))}) ] negated: False ) ] ) left_token: spids: [1304 1328] ) } spids: [1303] ) ] spids: [1303] ) (C {(test_expect_success)} {(DQ ("clone ssh://") ($ VSub_Name "$tuah") (/home/user/repo))} { (DQ ("\n") ("\t test_clone_url ssh://") ($ VSub_Name "$tuah") ("/home/user/repo ") ($ VSub_Name "$ehost") (" /home/user/repo\n") ("\t") ) } ) ] spids: [1300 1349] ) spids: [1242 -1] ) (ForEach iter_name: tuah iter_words: [ {(Lit_Other ":") (Lit_Other ":") (1)} {(Lit_Other "[") (Lit_Other ":") (Lit_Other ":") (1) (Lit_Other "]")} {(user) (Lit_Other "@") (Lit_Other ":") (Lit_Other ":") (1)} {(user) (Lit_Other "@") (Lit_Other "[") (Lit_Other ":") (Lit_Other ":") (1) (Lit_Other "]")} {(Lit_Other "[") (user) (Lit_Other "@") (Lit_Other ":") (Lit_Other ":") (1) (Lit_Other "]")} ] do_arg_iter: False body: (DoGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:euah) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(echo)} {($ VSub_Name "$tuah")}) (C {(tr)} {(-d)} {(DQ ("[]"))}) ] negated: False ) ] ) left_token: spids: [1397 1411] ) } spids: [1396] ) ] spids: [1396] ) (C {(test_expect_success)} {(DQ ("clone ssh://") ($ VSub_Name "$tuah") ("/~repo"))} { (DQ ("\n") ("\t test_clone_url ssh://") ($ VSub_Name "$tuah") ("/~repo ") ($ VSub_Name "$euah") (" '~repo'\n") ("\t") ) } ) ] spids: [1393 1432] ) spids: [1360 -1] ) (ForEach iter_name: tuah iter_words: [ {(Lit_Other "[") (Lit_Other ":") (Lit_Other ":") (1) (Lit_Other "]")} {(user) (Lit_Other "@") (Lit_Other "[") (Lit_Other ":") (Lit_Other ":") (1) (Lit_Other "]")} {(Lit_Other "[") (user) (Lit_Other "@") (Lit_Other ":") (Lit_Other ":") (1) (Lit_Other "]")} ] do_arg_iter: False body: (DoGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:euah) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(echo)} {($ VSub_Name "$tuah")}) (C {(tr)} {(-d)} {(DQ ("[]"))}) ] negated: False ) ] ) left_token: spids: [1470 1484] ) } spids: [1469] ) ] spids: [1469] ) (C {(test_expect_success)} {(DQ ("clone ssh://") ($ VSub_Name "$tuah") (":22/home/user/repo"))} { (DQ ("\n") ("\t test_clone_url ssh://") ($ VSub_Name "$tuah") (":22/home/user/repo '-p 22' ") ($ VSub_Name "$euah") (" /home/user/repo\n") ("\t") ) } ) ] spids: [1466 1505] ) spids: [1443 -1] ) (ForEach iter_name: tuah iter_words: [ {(Lit_Other "[") (Lit_Other ":") (Lit_Other ":") (1) (Lit_Other "]")} {(user) (Lit_Other "@") (Lit_Other "[") (Lit_Other ":") (Lit_Other ":") (1) (Lit_Other "]")} {(Lit_Other "[") (user) (Lit_Other "@") (Lit_Other ":") (Lit_Other ":") (1) (Lit_Other "]")} ] do_arg_iter: False body: (DoGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:euah) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(echo)} {($ VSub_Name "$tuah")}) (C {(tr)} {(-d)} {(DQ ("[]"))}) ] negated: False ) ] ) left_token: spids: [1543 1557] ) } spids: [1542] ) ] spids: [1542] ) (C {(test_expect_success)} {(DQ ("clone ssh://") ($ VSub_Name "$tuah") (":22/~repo"))} { (DQ ("\n") ("\t test_clone_url ssh://") ($ VSub_Name "$tuah") (":22/~repo '-p 22' ") ($ VSub_Name "$euah") (" '~repo'\n") ("\t") ) } ) ] spids: [1539 1578] ) spids: [1516 -1] ) (C {(test_expect_success)} {(SQ <"clone from a repository with two identical branches">)} { (SQ <"\n"> <"\n"> <"\t(\n"> <"\t\tcd src &&\n"> <"\t\tgit checkout -b another master\n"> <"\t) &&\n"> <"\tgit clone src target-11 &&\n"> <"\ttest \"z$( cd target-11 && git symbolic-ref HEAD )\" = zrefs/heads/another\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"shallow clone locally">)} { (SQ <"\n"> <"\tgit clone --depth=1 --no-local src ssrrcc &&\n"> <"\tgit clone ssrrcc ddsstt &&\n"> <"\ttest_cmp ssrrcc/.git/shallow ddsstt/.git/shallow &&\n"> <"\t( cd ddsstt && git fsck )\n"> ) } ) (C {(test_expect_success)} {(SQ <"GIT_TRACE_PACKFILE produces a usable pack">)} { (SQ <"\n"> <"\trm -rf dst.git &&\n"> <"\tGIT_TRACE_PACKFILE=$PWD/tmp.pack git clone --no-local --bare src dst.git &&\n"> <"\tgit init --bare replay.git &&\n"> <"\tgit -C replay.git index-pack -v --stdin ) } ) (C {(test_done)}) ] )