Code

Test for packed tags in git-describe output
[git.git] / git-clone.sh
index ecf9d89a108484af3f73817e60c523f1dca8fff0..e98112277839349a47c26e69ce30982604d12d2c 100755 (executable)
@@ -56,11 +56,12 @@ fi
 
 http_fetch () {
        # $1 = Remote, $2 = Local
-       curl -nsfL $curl_extra_args "$1" >"$2" ||
-               case $? in
-               126|127) exit ;;
-               *)       return $? ;;
-               esac
+       curl -nsfL $curl_extra_args "$1" >"$2"
+       curl_exit_status=$?
+       case $curl_exit_status in
+       126|127) exit ;;
+       *)       return $curl_exit_status ;;
+       esac
 }
 
 clone_dumb_http () {
@@ -151,7 +152,7 @@ do
                die "clones are always made with separate-remote layout" ;;
        --reference)
                shift; reference="$1" ;;
-       -o,--origin)
+       -o|--origin)
                shift;
                case "$1" in
                '')
@@ -205,12 +206,32 @@ fi
 # it is local
 if base=$(get_repo_base "$repo"); then
        repo="$base"
-       local=yes
+       if test -z "$depth"
+       then
+               local=yes
+       fi
+elif test -f "$repo"
+then
+       case "$repo" in /*) ;; *) repo="$PWD/$repo" ;; esac
+fi
+
+# Decide the directory name of the new repository
+if test -n "$2"
+then
+       dir="$2"
+else
+       # Derive one from the repository name
+       # Try using "humanish" part of source repo if user didn't specify one
+       if test -f "$repo"
+       then
+               # Cloning from a bundle
+               dir=$(echo "$repo" | sed -e 's|/*\.bundle$||' -e 's|.*/||g')
+       else
+               dir=$(echo "$repo" |
+                       sed -e 's|/$||' -e 's|:*/*\.git$||' -e 's|.*[/:]||g')
+       fi
 fi
 
-dir="$2"
-# Try using "humanish" part of source repo if user didn't specify one
-[ -z "$dir" ] && dir=$(echo "$repo" | sed -e 's|/$||' -e 's|:*/*\.git$||' -e 's|.*[/:]||g')
 [ -e "$dir" ] && die "destination directory '$dir' already exists."
 [ yes = "$bare" ] && unset GIT_WORK_TREE
 [ -n "$GIT_WORK_TREE" ] && [ -e "$GIT_WORK_TREE" ] &&
@@ -297,7 +318,8 @@ yes)
                                      find objects -type f -print | sed -e 1q)
                        # objects directory should not be empty because
                        # we are cloning!
-                       test -f "$repo/$sample_file" || exit
+                       test -f "$repo/$sample_file" ||
+                               die "fatal: cannot clone empty repository"
                        if ln "$repo/$sample_file" "$GIT_DIR/objects/sample" 2>/dev/null
                        then
                                rm -f "$GIT_DIR/objects/sample"
@@ -359,11 +381,17 @@ yes)
                fi
                ;;
        *)
-               case "$upload_pack" in
-               '') git-fetch-pack --all -k $quiet $depth $no_progress "$repo";;
-               *) git-fetch-pack --all -k $quiet "$upload_pack" $depth $no_progress "$repo" ;;
-               esac >"$GIT_DIR/CLONE_HEAD" ||
+               if [ -f "$repo" ] ; then
+                       git bundle unbundle "$repo" > "$GIT_DIR/CLONE_HEAD" ||
+                       die "unbundle from '$repo' failed."
+               else
+                       case "$upload_pack" in
+                       '') git-fetch-pack --all -k $quiet $depth $no_progress "$repo";;
+                       *) git-fetch-pack --all -k \
+                               $quiet "$upload_pack" $depth $no_progress "$repo" ;;
+                       esac >"$GIT_DIR/CLONE_HEAD" ||
                        die "fetch-pack from '$repo' failed."
+               fi
                ;;
        esac
        ;;
@@ -404,11 +432,12 @@ else
        cd "$D" || exit
 fi
 
-if test -z "$bare" && test -f "$GIT_DIR/REMOTE_HEAD"
+if test -z "$bare"
 then
        # a non-bare repository is always in separate-remote layout
        remote_top="refs/remotes/$origin"
-       head_sha1=`cat "$GIT_DIR/REMOTE_HEAD"`
+       head_sha1=
+       test ! -r "$GIT_DIR/REMOTE_HEAD" || head_sha1=`cat "$GIT_DIR/REMOTE_HEAD"`
        case "$head_sha1" in
        'ref: refs/'*)
                # Uh-oh, the remote told us (http transport done against
@@ -465,9 +494,16 @@ then
                git config branch."$head_points_at".merge "refs/heads/$head_points_at"
                ;;
        '')
-               # Source had detached HEAD pointing nowhere
-               git update-ref --no-deref HEAD "$head_sha1" &&
-               rm -f "refs/remotes/$origin/HEAD"
+               if test -z "$head_sha1"
+               then
+                       # Source had nonexistent ref in HEAD
+                       echo >&2 "Warning: Remote HEAD refers to nonexistent ref, unable to checkout."
+                       no_checkout=t
+               else
+                       # Source had detached HEAD pointing nowhere
+                       git update-ref --no-deref HEAD "$head_sha1" &&
+                       rm -f "refs/remotes/$origin/HEAD"
+               fi
                ;;
        esac