packaging: Add contrib installation
[platform/upstream/git.git] / t / t5601-clone.sh
index bfdaf75..7df3c53 100755 (executable)
@@ -4,6 +4,9 @@ test_description=clone
 
 . ./test-lib.sh
 
+X=
+test_have_prereq !MINGW || X=.exe
+
 test_expect_success setup '
 
        rm -fr .git &&
@@ -65,6 +68,29 @@ test_expect_success 'clone respects GIT_WORK_TREE' '
 
 '
 
+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 &&
@@ -125,7 +151,7 @@ test_expect_success 'clone --mirror does not repeat tags' '
        git clone --mirror src mirror2 &&
        (cd mirror2 &&
         git show-ref 2> clone.err > clone.out) &&
-       test_must_fail grep Duplicate mirror2/clone.err &&
+       ! grep Duplicate mirror2/clone.err &&
        grep some-tag mirror2/clone.out
 
 '
@@ -221,7 +247,7 @@ test_expect_success 'clone separate gitdir' '
 '
 
 test_expect_success 'clone separate gitdir: output' '
-       echo "gitdir: `pwd`/realgitdir" >expected &&
+       echo "gitdir: $(pwd)/realgitdir" >expected &&
        test_cmp expected dst/.git
 '
 
@@ -245,7 +271,9 @@ test_expect_success 'fetch from gitfile parent' '
 
 test_expect_success 'clone separate gitdir where target already exists' '
        rm -rf dst &&
-       test_must_fail git clone --separate-git-dir realgitdir src dst
+       echo foo=bar >>realgitdir/config &&
+       test_must_fail git clone --separate-git-dir realgitdir src dst &&
+       grep foo=bar realgitdir/config
 '
 
 test_expect_success 'clone --reference from original' '
@@ -280,26 +308,21 @@ test_expect_success 'clone checking out a tag' '
        test_cmp fetch.expected fetch.actual
 '
 
-setup_ssh_wrapper () {
-       test_expect_success 'setup ssh wrapper' '
-               write_script "$TRASH_DIRECTORY/ssh-wrapper" <<-\EOF &&
-               echo >>"$TRASH_DIRECTORY/ssh-output" "ssh: $*" &&
-               # throw away all but the last argument, which should be the
-               # command
-               while test $# -gt 1; do shift; done
-               eval "$1"
-               EOF
-               GIT_SSH="$TRASH_DIRECTORY/ssh-wrapper" &&
-               export GIT_SSH &&
-               export TRASH_DIRECTORY &&
-               >"$TRASH_DIRECTORY"/ssh-output
-       '
-}
+test_expect_success 'set up ssh wrapper' '
+       cp "$GIT_BUILD_DIR/t/helper/test-fake-ssh$X" \
+               "$TRASH_DIRECTORY/ssh$X" &&
+       GIT_SSH="$TRASH_DIRECTORY/ssh$X" &&
+       export GIT_SSH &&
+       export TRASH_DIRECTORY &&
+       >"$TRASH_DIRECTORY"/ssh-output
+'
 
 copy_ssh_wrapper_as () {
-       cp "$TRASH_DIRECTORY/ssh-wrapper" "$1" &&
-       GIT_SSH="$1" &&
-       export GIT_SSH
+       rm -f "${1%$X}$X" &&
+       cp "$TRASH_DIRECTORY/ssh$X" "${1%$X}$X" &&
+       test_when_finished "rm $(git rev-parse --sq-quote "${1%$X}$X")" &&
+       GIT_SSH="${1%$X}$X" &&
+       test_when_finished "GIT_SSH=\"\$TRASH_DIRECTORY/ssh\$X\""
 }
 
 expect_ssh () {
@@ -323,10 +346,8 @@ expect_ssh () {
        (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 &&
+       GIT_TEST_PROTOCOL_VERSION=0 git clone myhost:src ssh-clone &&
        expect_ssh myhost src
 '
 
@@ -337,13 +358,56 @@ test_expect_success !MINGW,!CYGWIN 'clone local path foo:bar' '
 '
 
 test_expect_success 'bracketed hostnames are still ssh' '
-       git clone "[myhost:123]:src" ssh-bracket-clone &&
+       GIT_TEST_PROTOCOL_VERSION=0 git clone "[myhost:123]:src" ssh-bracket-clone &&
        expect_ssh "-p 123" myhost src
 '
 
-test_expect_success 'uplink is not treated as putty' '
+test_expect_success 'OpenSSH variant passes -4' '
+       GIT_TEST_PROTOCOL_VERSION=0 git clone -4 "[myhost:123]:src" ssh-ipv4-clone &&
+       expect_ssh "-4 -p 123" myhost src
+'
+
+test_expect_success 'variant can be overridden' '
+       copy_ssh_wrapper_as "$TRASH_DIRECTORY/putty" &&
+       git -c ssh.variant=putty clone -4 "[myhost:123]:src" ssh-putty-clone &&
+       expect_ssh "-4 -P 123" myhost src
+'
+
+test_expect_success 'variant=auto picks based on basename' '
+       copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink" &&
+       git -c ssh.variant=auto clone -4 "[myhost:123]:src" ssh-auto-clone &&
+       expect_ssh "-4 -P 123" myhost src
+'
+
+test_expect_success 'simple does not support -4/-6' '
+       copy_ssh_wrapper_as "$TRASH_DIRECTORY/simple" &&
+       test_must_fail git clone -4 "myhost:src" ssh-4-clone-simple
+'
+
+test_expect_success 'simple does not support port' '
+       copy_ssh_wrapper_as "$TRASH_DIRECTORY/simple" &&
+       test_must_fail git clone "[myhost:123]:src" ssh-bracket-clone-simple
+'
+
+test_expect_success 'uplink is treated as simple' '
        copy_ssh_wrapper_as "$TRASH_DIRECTORY/uplink" &&
-       git clone "[myhost:123]:src" ssh-bracket-clone-uplink &&
+       test_must_fail git clone "[myhost:123]:src" ssh-bracket-clone-uplink &&
+       git clone "myhost:src" ssh-clone-uplink &&
+       expect_ssh myhost src
+'
+
+test_expect_success 'OpenSSH-like uplink is treated as ssh' '
+       write_script "$TRASH_DIRECTORY/uplink" <<-EOF &&
+       if test "\$1" = "-G"
+       then
+               exit 0
+       fi &&
+       exec "\$TRASH_DIRECTORY/ssh$X" "\$@"
+       EOF
+       test_when_finished "rm -f \"\$TRASH_DIRECTORY/uplink\"" &&
+       GIT_SSH="$TRASH_DIRECTORY/uplink" &&
+       test_when_finished "GIT_SSH=\"\$TRASH_DIRECTORY/ssh\$X\"" &&
+       GIT_TEST_PROTOCOL_VERSION=0 git clone "[myhost:123]:src" ssh-bracket-clone-sshlike-uplink &&
        expect_ssh "-p 123" myhost src
 '
 
@@ -365,8 +429,53 @@ test_expect_success 'tortoiseplink is like putty, with extra arguments' '
        expect_ssh "-batch -P 123" myhost src
 '
 
-# Reset the GIT_SSH environment variable for clone tests.
-setup_ssh_wrapper
+test_expect_success 'double quoted plink.exe in GIT_SSH_COMMAND' '
+       copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink.exe" &&
+       GIT_SSH_COMMAND="\"$TRASH_DIRECTORY/plink.exe\" -v" \
+               git clone "[myhost:123]:src" ssh-bracket-clone-plink-3 &&
+       expect_ssh "-v -P 123" myhost src
+'
+
+test_expect_success 'single quoted plink.exe in GIT_SSH_COMMAND' '
+       copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink.exe" &&
+       GIT_SSH_COMMAND="$SQ$TRASH_DIRECTORY/plink.exe$SQ -v" \
+               git clone "[myhost:123]:src" ssh-bracket-clone-plink-4 &&
+       expect_ssh "-v -P 123" myhost src
+'
+
+test_expect_success 'GIT_SSH_VARIANT overrides plink detection' '
+       copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink" &&
+       GIT_TEST_PROTOCOL_VERSION=0 GIT_SSH_VARIANT=ssh \
+               git clone "[myhost:123]:src" ssh-bracket-clone-variant-1 &&
+       expect_ssh "-p 123" myhost src
+'
+
+test_expect_success 'ssh.variant overrides plink detection' '
+       copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink" &&
+       GIT_TEST_PROTOCOL_VERSION=0 git -c ssh.variant=ssh \
+               clone "[myhost:123]:src" ssh-bracket-clone-variant-2 &&
+       expect_ssh "-p 123" myhost src
+'
+
+test_expect_success 'GIT_SSH_VARIANT overrides plink detection to plink' '
+       copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink" &&
+       GIT_SSH_VARIANT=plink \
+       git clone "[myhost:123]:src" ssh-bracket-clone-variant-3 &&
+       expect_ssh "-P 123" myhost src
+'
+
+test_expect_success 'GIT_SSH_VARIANT overrides plink to tortoiseplink' '
+       copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink" &&
+       GIT_SSH_VARIANT=tortoiseplink \
+       git clone "[myhost:123]:src" ssh-bracket-clone-variant-4 &&
+       expect_ssh "-batch -P 123" myhost src
+'
+
+test_expect_success 'clean failure on broken quoting' '
+       test_must_fail \
+               env GIT_SSH_COMMAND="${SQ}plink.exe -v" \
+               git clone "[myhost:123]:src" sq-failure
+'
 
 counter=0
 # $1 url
@@ -374,12 +483,12 @@ counter=0
 # $3 path
 test_clone_url () {
        counter=$(($counter + 1))
-       test_might_fail git clone "$1" tmp$counter &&
+       test_might_fail env GIT_TEST_PROTOCOL_VERSION=0 git clone "$1" tmp$counter &&
        shift &&
        expect_ssh "$@"
 }
 
-test_expect_success !MINGW 'clone c:temp is ssl' '
+test_expect_success !MINGW,!CYGWIN 'clone c:temp is ssl' '
        test_clone_url c:temp c temp
 '
 
@@ -445,7 +554,7 @@ test_expect_success 'clone ssh://host.xz:22/~repo' '
 #IPv6
 for tuah in ::1 [::1] [::1]: user@::1 user@[::1] user@[::1]: [user@::1] [user@::1]:
 do
-       ehost=$(echo $tuah | sed -e "s/1]:/1]/ "| tr -d "[]")
+       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
        "
@@ -496,4 +605,158 @@ test_expect_success 'shallow clone locally' '
        ( 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 <tmp.pack
+'
+
+test_expect_success 'clone on case-insensitive fs' '
+       git init icasefs &&
+       (
+               cd icasefs &&
+               o=$(git hash-object -w --stdin </dev/null | hex2oct) &&
+               t=$(printf "100644 X\0${o}100644 x\0${o}" |
+                       git hash-object -w -t tree --stdin) &&
+               c=$(git commit-tree -m bogus $t) &&
+               git update-ref refs/heads/bogus $c &&
+               git clone -b bogus . bogus 2>warning
+       )
+'
+
+test_expect_success CASE_INSENSITIVE_FS 'colliding file detection' '
+       grep X icasefs/warning &&
+       grep x icasefs/warning &&
+       test_i18ngrep "the following paths have collided" icasefs/warning
+'
+
+test_expect_success 'clone with GIT_DEFAULT_HASH' '
+       (
+               sane_unset GIT_DEFAULT_HASH &&
+               git init --object-format=sha1 test-sha1 &&
+               git init --object-format=sha256 test-sha256
+       ) &&
+       test_commit -C test-sha1 foo &&
+       test_commit -C test-sha256 foo &&
+       GIT_DEFAULT_HASH=sha1 git clone test-sha256 test-clone-sha256 &&
+       GIT_DEFAULT_HASH=sha256 git clone test-sha1 test-clone-sha1 &&
+       git -C test-clone-sha1 status &&
+       git -C test-clone-sha256 status
+'
+
+partial_clone_server () {
+              SERVER="$1" &&
+
+       rm -rf "$SERVER" client &&
+       test_create_repo "$SERVER" &&
+       test_commit -C "$SERVER" one &&
+       HASH1=$(git -C "$SERVER" hash-object one.t) &&
+       git -C "$SERVER" revert HEAD &&
+       test_commit -C "$SERVER" two &&
+       HASH2=$(git -C "$SERVER" hash-object two.t) &&
+       test_config -C "$SERVER" uploadpack.allowfilter 1 &&
+       test_config -C "$SERVER" uploadpack.allowanysha1inwant 1
+}
+
+partial_clone () {
+              SERVER="$1" &&
+              URL="$2" &&
+
+       partial_clone_server "${SERVER}" &&
+       git clone --filter=blob:limit=0 "$URL" client &&
+
+       git -C client fsck &&
+
+       # Ensure that unneeded blobs are not inadvertently fetched.
+       test_config -C client remote.origin.promisor "false" &&
+       git -C client config --unset remote.origin.partialclonefilter &&
+       test_must_fail git -C client cat-file -e "$HASH1" &&
+
+       # But this blob was fetched, because clone performs an initial checkout
+       git -C client cat-file -e "$HASH2"
+}
+
+test_expect_success 'partial clone' '
+       partial_clone server "file://$(pwd)/server"
+'
+
+test_expect_success 'partial clone with -o' '
+       partial_clone_server server &&
+       git clone -o blah --filter=blob:limit=0 "file://$(pwd)/server" client &&
+       test_cmp_config -C client "blob:limit=0" --get-all remote.blah.partialclonefilter
+'
+
+test_expect_success 'partial clone: warn if server does not support object filtering' '
+       rm -rf server client &&
+       test_create_repo server &&
+       test_commit -C server one &&
+
+       git clone --filter=blob:limit=0 "file://$(pwd)/server" client 2> err &&
+
+       test_i18ngrep "filtering not recognized by server" err
+'
+
+test_expect_success 'batch missing blob request during checkout' '
+       rm -rf server client &&
+
+       test_create_repo server &&
+       echo a >server/a &&
+       echo b >server/b &&
+       git -C server add a b &&
+
+       git -C server commit -m x &&
+       echo aa >server/a &&
+       echo bb >server/b &&
+       git -C server add a b &&
+       git -C server commit -m x &&
+
+       test_config -C server uploadpack.allowfilter 1 &&
+       test_config -C server uploadpack.allowanysha1inwant 1 &&
+
+       git clone --filter=blob:limit=0 "file://$(pwd)/server" client &&
+
+       # Ensure that there is only one negotiation by checking that there is
+       # only "done" line sent. ("done" marks the end of negotiation.)
+       GIT_TRACE_PACKET="$(pwd)/trace" git -C client checkout HEAD^ &&
+       grep "fetch> done" trace >done_lines &&
+       test_line_count = 1 done_lines
+'
+
+test_expect_success 'batch missing blob request does not inadvertently try to fetch gitlinks' '
+       rm -rf server client &&
+
+       test_create_repo repo_for_submodule &&
+       test_commit -C repo_for_submodule x &&
+
+       test_create_repo server &&
+       echo a >server/a &&
+       echo b >server/b &&
+       git -C server add a b &&
+       git -C server commit -m x &&
+
+       echo aa >server/a &&
+       echo bb >server/b &&
+       # Also add a gitlink pointing to an arbitrary repository
+       git -C server submodule add "$(pwd)/repo_for_submodule" c &&
+       git -C server add a b c &&
+       git -C server commit -m x &&
+
+       test_config -C server uploadpack.allowfilter 1 &&
+       test_config -C server uploadpack.allowanysha1inwant 1 &&
+
+       # Make sure that it succeeds
+       git clone --filter=blob:limit=0 "file://$(pwd)/server" client
+'
+
+. "$TEST_DIRECTORY"/lib-httpd.sh
+start_httpd
+
+test_expect_success 'partial clone using HTTP' '
+       partial_clone "$HTTPD_DOCUMENT_ROOT_PATH/server" "$HTTPD_URL/smart/server"
+'
+
+# DO NOT add non-httpd-specific tests here, because the last part of this
+# test script is only executed when httpd is available and enabled.
+
 test_done