commit: fix a segfault when displaying a commit with unreachable parents
[gitweb.git] / git-fetch.sh
index 48818f822451b3d69e7cd90e81e34bf137ead4dd..79222fbb1a4bf3205f3225feafc96aa43aace87c 100755 (executable)
@@ -11,6 +11,7 @@ LF='
 '
 IFS="$LF"
 
+rloga=fetch
 no_tags=
 tags=
 append=
@@ -19,6 +20,7 @@ verbose=
 update_head_ok=
 exec=
 upload_pack=
+keep=--thin
 while case "$#" in 0) break ;; esac
 do
        case "$1" in
@@ -51,6 +53,9 @@ do
        -k|--k|--ke|--kee|--keep)
                keep=--keep
                ;;
+       --reflog-action=*)
+               rloga=`expr "z$1" : 'z-[^=]*=\(.*\)'`
+               ;;
        -*)
                usage
                ;;
@@ -63,10 +68,10 @@ done
 
 case "$#" in
 0)
-       test -f "$GIT_DIR/branches/origin" ||
-               test -f "$GIT_DIR/remotes/origin" ||
-                       die "Where do you want to fetch from today?"
-       set origin ;;
+       origin=$(get_default_remote)
+       test -n "$(get_remote_url ${origin})" ||
+               die "Where do you want to fetch from today?"
+       set x $origin ; shift ;;
 esac
 
 remote_nick="$1"
@@ -75,6 +80,9 @@ refs=
 rref=
 rsync_slurped_objects=
 
+rloga="$rloga $remote_nick"
+test "$remote_nick" = "$remote" || rloga="$rloga $remote"
+
 if test "" = "$append"
 then
        : >"$GIT_DIR/FETCH_HEAD"
@@ -146,14 +154,15 @@ fast_forward_local () {
        then
                if now_=$(cat "$GIT_DIR/$1") && test "$now_" = "$2"
                then
-                       [ "$verbose" ] && echo >&2 "* $1: same as $3"
+                       [ "$verbose" ] && echo >&2 "* $1: same as $3" ||:
                else
                        echo >&2 "* $1: updating with $3"
+                       git-update-ref -m "$rloga: updating tag" "$1" "$2"
                fi
        else
                echo >&2 "* $1: storing $3"
+               git-update-ref -m "$rloga: storing tag" "$1" "$2"
        fi
-       git-update-ref "$1" "$2"
        ;;
 
     refs/heads/* | refs/remotes/*)
@@ -174,7 +183,7 @@ fast_forward_local () {
            *,$local)
                echo >&2 "* $1: fast forward to $3"
                echo >&2 "  from $local to $2"
-               git-update-ref "$1" "$2" "$local"
+               git-update-ref -m "$rloga: fast-forward" "$1" "$2" "$local"
                ;;
            *)
                false
@@ -184,7 +193,7 @@ fast_forward_local () {
                case ",$force,$single_force," in
                *,t,*)
                        echo >&2 "  forcing update."
-                       git-update-ref "$1" "$2" "$local"
+                       git-update-ref -m "$rloga: forced-update" "$1" "$2" "$local"
                        ;;
                *)
                        echo >&2 "  not updating."
@@ -194,7 +203,7 @@ fast_forward_local () {
            }
        else
            echo >&2 "* $1: storing $3"
-           git-update-ref "$1" "$2"
+           git-update-ref -m "$rloga: storing head" "$1" "$2"
        fi
        ;;
     esac
@@ -215,9 +224,16 @@ reflist=$(get_remote_refs_for_fetch "$@")
 if test "$tags"
 then
        taglist=`IFS="  " &&
-                 git-ls-remote $upload_pack --tags "$remote" |
+                 (
+                       git-ls-remote $upload_pack --tags "$remote" ||
+                       echo fail ouch
+                 ) |
                  while read sha1 name
                  do
+                       case "$sha1" in
+                       fail)
+                               exit 1
+                       esac
                        case "$name" in
                        *^*) continue ;;
                        esac
@@ -227,7 +243,7 @@ then
                        else
                            echo >&2 "warning: tag ${name} ignored"
                        fi
-                 done`
+                 done` || exit
        if test "$#" -gt 1
        then
                # remote URL plus explicit refspecs; we need to merge them.
@@ -241,6 +257,7 @@ fi
 fetch_main () {
   reflist="$1"
   refs=
+  rref=
 
   for ref in $reflist
   do
@@ -269,22 +286,26 @@ fetch_main () {
 
       # There are transports that can fetch only one head at a time...
       case "$remote" in
-      http://* | https://*)
+      http://* | https://* | ftp://*)
          if [ -n "$GIT_SSL_NO_VERIFY" ]; then
              curl_extra_args="-k"
          fi
+         if [ -n "$GIT_CURL_FTP_NO_EPSV" -o \
+               "`git-repo-config --bool http.noEPSV`" = true ]; then
+             noepsv_opt="--disable-epsv"
+         fi
          max_depth=5
          depth=0
          head="ref: $remote_name"
          while (expr "z$head" : "zref:" && expr $depth \< $max_depth) >/dev/null
          do
-           remote_name_quoted=$(perl -e '
+           remote_name_quoted=$(@@PERL@@ -e '
              my $u = $ARGV[0];
               $u =~ s/^ref:\s*//;
              $u =~ s{([^-a-zA-Z0-9/.])}{sprintf"%%%02x",ord($1)}eg;
              print "$u";
          ' "$head")
-           head=$(curl -nsfL $curl_extra_args "$remote/$remote_name_quoted")
+           head=$(curl -nsfL $curl_extra_args $noepsv_opt "$remote/$remote_name_quoted")
            depth=$( expr \( $depth + 1 \) )
          done
          expr "z$head" : "z$_x40\$" >/dev/null ||
@@ -333,13 +354,13 @@ fetch_main () {
   done
 
   case "$remote" in
-  http://* | https://* | rsync://* )
+  http://* | https://* | ftp://* | rsync://* )
       ;; # we are already done.
   *)
     ( : subshell because we muck with IFS
       IFS="    $LF"
       (
-         git-fetch-pack $exec $keep --thin "$remote" $rref || echo failed "$remote"
+         git-fetch-pack $exec $keep "$remote" $rref || echo failed "$remote"
       ) |
       while read sha1 remote_name
       do
@@ -415,14 +436,16 @@ esac
 
 # If the original head was empty (i.e. no "master" yet), or
 # if we were told not to worry, we do not have to check.
-case ",$update_head_ok,$orig_head," in
-*,, | t,* )
+case "$orig_head" in
+'')
        ;;
-*)
+?*)
        curr_head=$(git-rev-parse --verify HEAD 2>/dev/null)
        if test "$curr_head" != "$orig_head"
        then
-               git-update-ref HEAD "$orig_head"
+           git-update-ref \
+                       -m "$rloga: Undoing incorrectly fetched HEAD." \
+                       HEAD "$orig_head"
                die "Cannot fetch into the current branch."
        fi
        ;;