git-fetch --tags: deal with tags with spaces in them.
[gitweb.git] / git-fetch.sh
index 61da6a9e3167845cf5b0f9260206b2dd590532df..7c05880bcfca30426d03112c0967ada6f68305be 100755 (executable)
@@ -5,6 +5,10 @@
 _x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
 _x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
 
+LF='
+'
+IFS="$LF"
+
 tags=
 append=
 force=
@@ -49,7 +53,7 @@ rsync_slurped_objects=
 
 if test "" = "$append"
 then
-       : >$GIT_DIR/FETCH_HEAD
+       : >"$GIT_DIR/FETCH_HEAD"
 fi
 
 append_fetch_head () {
@@ -86,11 +90,11 @@ append_fetch_head () {
     if git-cat-file commit "$head_" >/dev/null 2>&1
     then
        headc_=$(git-rev-parse --verify "$head_^0") || exit
-       echo "$headc_   $not_for_merge_ $note_" >>$GIT_DIR/FETCH_HEAD
+       echo "$headc_   $not_for_merge_ $note_" >>"$GIT_DIR/FETCH_HEAD"
        echo >&2 "* committish: $head_"
        echo >&2 "  $note_"
     else
-       echo "$head_    not-for-merge   $note_" >>$GIT_DIR/FETCH_HEAD
+       echo "$head_    not-for-merge   $note_" >>"$GIT_DIR/FETCH_HEAD"
        echo >&2 "* non-commit: $head_"
        echo >&2 "  $note_"
     fi
@@ -170,11 +174,14 @@ esac
 reflist=$(get_remote_refs_for_fetch "$@")
 if test "$tags"
 then
-       taglist=$(git-ls-remote --tags "$remote" | awk '{ print "."$2":"$2 }')
+       taglist=$(git-ls-remote --tags "$remote" |
+               sed -e '
+                       s/^[^   ]*      //
+                       s/.*/&:&/')
        if test "$#" -gt 1
        then
                # remote URL plus explicit refspecs; we need to merge them.
-               reflist="$reflist $taglist"
+               reflist="$reflist$LF$taglist"
        else
                # No explicit refspecs; fetch tags only.
                reflist=$taglist
@@ -183,7 +190,7 @@ fi
 
 for ref in $reflist
 do
-    refs="$refs $ref"
+    refs="$refs$LF$ref"
 
     # These are relative path from $GIT_DIR, typically starting at refs/
     # but may be HEAD
@@ -204,7 +211,7 @@ do
     remote_name=$(expr "$ref" : '\([^:]*\):')
     local_name=$(expr "$ref" : '[^:]*:\(.*\)')
 
-    rref="$rref $remote_name"
+    rref="$rref$LF$remote_name"
 
     # There are transports that can fetch only one head at a time...
     case "$remote" in
@@ -212,7 +219,12 @@ do
        if [ -n "$GIT_SSL_NO_VERIFY" ]; then
            curl_extra_args="-k"
        fi
-       head=$(curl -nsf $curl_extra_args "$remote/$remote_name") &&
+       remote_name_quoted=$(perl -e '
+           my $u = $ARGV[0];
+           $u =~ s{([^-a-zA-Z0-9/.])}{sprintf"%%%02x",ord($1)}eg;
+           print "$u";
+       ' "$remote_name")
+       head=$(curl -nsf $curl_extra_args "$remote/$remote_name_quoted") &&
        expr "$head" : "$_x40\$" >/dev/null ||
                die "Failed to fetch $remote_name from $remote"
        echo >&2 Fetching "$remote_name from $remote" using http
@@ -262,6 +274,7 @@ case "$remote" in
 http://* | https://* | rsync://* )
     ;; # we are already done.
 *)
+    IFS="      $LF"
     (
        git-fetch-pack "$remote" $rref || echo failed "$remote"
     ) |