GIT 1.4.3-rc1
[gitweb.git] / git-clone.sh
index 6887321972aab5825734dd81560f9c8cdd010660..3998c55cef3658eda18817d513a5bd5003c30e89 100755 (executable)
@@ -9,7 +9,7 @@
 unset CDPATH
 
 usage() {
-       echo >&2 "Usage: $0 [--use-separate-remote] [--reference <reference-repo>] [--bare] [-l [-s]] [-q] [-u <upload-pack>] [-o <name>] [-n] <repo> [<dir>]"
+       echo >&2 "Usage: $0 [--template=<template_directory>] [--use-separate-remote] [--reference <reference-repo>] [--bare] [-l [-s]] [-q] [-u <upload-pack>] [--origin <name>] [-n] <repo> [<dir>]"
        exit 1
 }
 
@@ -29,8 +29,12 @@ http_fetch () {
 clone_dumb_http () {
        # $1 - remote, $2 - local
        cd "$2" &&
-       clone_tmp='.git/clone-tmp' &&
+       clone_tmp="$GIT_DIR/clone-tmp" &&
        mkdir -p "$clone_tmp" || exit 1
+       if [ -n "$GIT_CURL_FTP_NO_EPSV" -o \
+               "`git-repo-config --bool http.noEPSV`" = true ]; then
+               curl_extra_args="${curl_extra_args} --disable-epsv"
+       fi
        http_fetch "$1/info/refs" "$clone_tmp/refs" || {
                echo >&2 "Cannot get remote repository information.
 Perhaps git-update-server-info needs to be run there?"
@@ -38,12 +42,12 @@ Perhaps git-update-server-info needs to be run there?"
        }
        while read sha1 refname
        do
-               name=`expr "$refname" : 'refs/\(.*\)'` &&
+               name=`expr "z$refname" : 'zrefs/\(.*\)'` &&
                case "$name" in
                *^*)    continue;;
                esac
                if test -n "$use_separate_remote" &&
-                  branch_name=`expr "$name" : 'heads/\(.*\)'`
+                  branch_name=`expr "z$name" : 'zheads/\(.*\)'`
                then
                        tname="remotes/$origin/$branch_name"
                else
@@ -52,7 +56,8 @@ Perhaps git-update-server-info needs to be run there?"
                git-http-fetch -v -a -w "$tname" "$name" "$1/" || exit 1
        done <"$clone_tmp/refs"
        rm -fr "$clone_tmp"
-       http_fetch "$1/HEAD" "$GIT_DIR/REMOTE_HEAD"
+       http_fetch "$1/HEAD" "$GIT_DIR/REMOTE_HEAD" ||
+       rm -f "$GIT_DIR/REMOTE_HEAD"
 }
 
 # Read git-fetch-pack -k output and store the remote branches.
@@ -98,8 +103,10 @@ close FH;
 '
 
 quiet=
+local=no
 use_local=no
 local_shared=no
+unset template
 no_checkout=
 upload_pack=
 bare=
@@ -118,17 +125,23 @@ while
        *,-l|*,--l|*,--lo|*,--loc|*,--loca|*,--local) use_local=yes ;;
         *,-s|*,--s|*,--sh|*,--sha|*,--shar|*,--share|*,--shared) 
           local_shared=yes; use_local=yes ;;
+       1,--template) usage ;;
+       *,--template)
+               shift; template="--template=$1" ;;
+       *,--template=*)
+         template="$1" ;;
        *,-q|*,--quiet) quiet=-q ;;
        *,--use-separate-remote)
                use_separate_remote=t ;;
-       1,-o) usage;;
        1,--reference) usage ;;
        *,--reference)
                shift; reference="$1" ;;
        *,--reference=*)
-               reference=`expr "$1" : '--reference=\(.*\)'` ;;
-       *,-o)
+               reference=`expr "z$1" : 'z--reference=\(.*\)'` ;;
+       *,-o|*,--or|*,--ori|*,--orig|*,--origi|*,--origin)
                case "$2" in
+               '')
+                   usage ;;
                */*)
                    echo >&2 "'$2' is not suitable for an origin name"
                    exit 1
@@ -138,7 +151,7 @@ while
                    exit 1
                }
                test -z "$origin_override" || {
-                   echo >&2 "Do not give more than one -o options."
+                   echo >&2 "Do not give more than one --origin options."
                    exit 1
                }
                origin_override=yes
@@ -155,12 +168,19 @@ do
        shift
 done
 
+repo="$1"
+if test -z "$repo"
+then
+    echo >&2 'you must specify a repository to clone.'
+    exit 1
+fi
+
 # --bare implies --no-checkout
 if test yes = "$bare"
 then
        if test yes = "$origin_override"
        then
-               echo >&2 '--bare and -o $origin options are incompatible.'
+               echo >&2 '--bare and --origin $origin options are incompatible.'
                exit 1
        fi
        if test t = "$use_separate_remote"
@@ -178,8 +198,6 @@ fi
 
 # Turn the source into an absolute path if
 # it is local
-repo="$1"
-local=no
 if base=$(get_repo_base "$repo"); then
        repo="$base"
        local=yes
@@ -191,17 +209,13 @@ dir="$2"
 [ -e "$dir" ] && echo "$dir already exists." && usage
 mkdir -p "$dir" &&
 D=$(cd "$dir" && pwd) &&
-trap 'err=$?; cd ..; rm -r "$D"; exit $err' exit
-case "$bare" in
-yes) GIT_DIR="$D" ;;
-*) GIT_DIR="$D/.git" ;;
-esac && export GIT_DIR && git-init-db || usage
+trap 'err=$?; cd ..; rm -rf "$D"; exit $err' 0
 case "$bare" in
 yes)
        GIT_DIR="$D" ;;
 *)
        GIT_DIR="$D/.git" ;;
-esac
+esac && export GIT_DIR && git-init-db ${template+"$template"} || usage
 
 if test -n "$reference"
 then
@@ -253,14 +267,10 @@ yes,yes)
            ;;
        yes)
            mkdir -p "$GIT_DIR/objects/info"
-           {
-               test -f "$repo/objects/info/alternates" &&
-               cat "$repo/objects/info/alternates";
-               echo "$repo/objects"
-           } >"$GIT_DIR/objects/info/alternates"
+           echo "$repo/objects" >> "$GIT_DIR/objects/info/alternates"
            ;;
        esac
-       git-ls-remote "$repo" >"$GIT_DIR/CLONE_HEAD"
+       git-ls-remote "$repo" >"$GIT_DIR/CLONE_HEAD" || exit 1
        ;;
 *)
        case "$repo" in
@@ -290,9 +300,9 @@ yes,yes)
                    done
                    rm -f "$GIT_DIR/TMP_ALT"
                fi
-               git-ls-remote "$repo" >"$GIT_DIR/CLONE_HEAD"
+               git-ls-remote "$repo" >"$GIT_DIR/CLONE_HEAD" || exit 1
                ;;
-       http://*)
+       https://*|http://*|ftp://*)
                if test -z "@@NO_CURL@@"
                then
                        clone_dumb_http "$repo" "$D"
@@ -317,30 +327,34 @@ test -d "$GIT_DIR/refs/reference-tmp" && rm -fr "$GIT_DIR/refs/reference-tmp"
 
 if test -f "$GIT_DIR/CLONE_HEAD"
 then
-       # Figure out where the remote HEAD points at.
-       perl -e "$copy_refs" "$GIT_DIR" "$use_separate_remote" "$origin"
+       # Read git-fetch-pack -k output and store the remote branches.
+       @@PERL@@ -e "$copy_refs" "$GIT_DIR" "$use_separate_remote" "$origin" ||
+       exit
 fi
 
 cd "$D" || exit
 
 if test -z "$bare" && test -f "$GIT_DIR/REMOTE_HEAD"
 then
-       head_sha1=`cat "$GIT_DIR/REMOTE_HEAD"`
        # Figure out which remote branch HEAD points at.
        case "$use_separate_remote" in
        '')     remote_top=refs/heads ;;
        *)      remote_top="refs/remotes/$origin" ;;
        esac
 
-       # What to use to track the remote primary branch
-       if test -n "$use_separate_remote"
-       then
-               origin_tracking="remotes/$origin/master"
-       else
-               origin_tracking="heads/$origin"
-       fi
+       head_sha1=`cat "$GIT_DIR/REMOTE_HEAD"`
+       case "$head_sha1" in
+       'ref: refs/'*)
+               # Uh-oh, the remote told us (http transport done against
+               # new style repository with a symref HEAD).
+               # Ideally we should skip the guesswork but for now
+               # opt for minimum change.
+               head_sha1=`expr "z$head_sha1" : 'zref: refs/heads/\(.*\)'`
+               head_sha1=`cat "$GIT_DIR/$remote_top/$head_sha1"`
+               ;;
+       esac
 
-       # The name under $remote_top the remote HEAD seems to point at
+       # The name under $remote_top the remote HEAD seems to point at.
        head_points_at=$(
                (
                        echo "master"
@@ -361,23 +375,33 @@ then
                )
        )
 
-       # Write out remotes/$origin file.
+       # Write out remotes/$origin file, and update our "$head_points_at".
        case "$head_points_at" in
        ?*)
                mkdir -p "$GIT_DIR/remotes" &&
-               echo >"$GIT_DIR/remotes/$origin" \
-               "URL: $repo
-Pull: refs/heads/$head_points_at:refs/$origin_tracking" &&
+               git-symbolic-ref HEAD "refs/heads/$head_points_at" &&
                case "$use_separate_remote" in
-               t) git-update-ref HEAD "$head_sha1" ;;
-               *) git-update-ref "refs/heads/$origin" $(git-rev-parse HEAD) ;;
+               t)      origin_track="$remote_top/$head_points_at"
+                       git-update-ref HEAD "$head_sha1" ;;
+               *)      origin_track="$remote_top/$origin"
+                       git-update-ref "refs/heads/$origin" "$head_sha1" ;;
                esac &&
+               echo >"$GIT_DIR/remotes/$origin" \
+               "URL: $repo
+Pull: refs/heads/$head_points_at:$origin_track" &&
                (cd "$GIT_DIR/$remote_top" && find . -type f -print) |
                while read dotslref
                do
-                       name=`expr "$dotslref" : './\(.*\)'` &&
-                       test "$head_points_at" = "$name" ||
-                       test "$origin" = "$name" ||
+                       name=`expr "$dotslref" : './\(.*\)'`
+                       if test "z$head_points_at" = "z$name"
+                       then
+                               continue
+                       fi
+                       if test "$use_separate_remote" = '' &&
+                          test "z$origin" = "z$name"
+                       then
+                               continue
+                       fi
                        echo "Pull: refs/heads/${name}:$remote_top/${name}"
                done >>"$GIT_DIR/remotes/$origin" &&
                case "$use_separate_remote" in
@@ -395,5 +419,5 @@ Pull: refs/heads/$head_points_at:refs/$origin_tracking" &&
 fi
 rm -f "$GIT_DIR/CLONE_HEAD" "$GIT_DIR/REMOTE_HEAD"
 
-trap - exit
+trap - 0