git-fetch.shon commit Convert output messages in merge-recursive to past tense. (89f40be)
   1#!/bin/sh
   2#
   3
   4USAGE='<fetch-options> <repository> <refspec>...'
   5SUBDIRECTORY_OK=Yes
   6. git-sh-setup
   7set_reflog_action "fetch $*"
   8cd_to_toplevel ;# probably unnecessary...
   9
  10. git-parse-remote
  11_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
  12_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
  13
  14LF='
  15'
  16IFS="$LF"
  17
  18no_tags=
  19tags=
  20append=
  21force=
  22verbose=
  23update_head_ok=
  24exec=
  25upload_pack=
  26keep=
  27shallow_depth=
  28while case "$#" in 0) break ;; esac
  29do
  30        case "$1" in
  31        -a|--a|--ap|--app|--appe|--appen|--append)
  32                append=t
  33                ;;
  34        --upl|--uplo|--uploa|--upload|--upload-|--upload-p|\
  35        --upload-pa|--upload-pac|--upload-pack)
  36                shift
  37                exec="--exec=$1" 
  38                upload_pack="-u $1"
  39                ;;
  40        -f|--f|--fo|--for|--forc|--force)
  41                force=t
  42                ;;
  43        -t|--t|--ta|--tag|--tags)
  44                tags=t
  45                ;;
  46        -n|--n|--no|--no-|--no-t|--no-ta|--no-tag|--no-tags)
  47                no_tags=t
  48                ;;
  49        -u|--u|--up|--upd|--upda|--updat|--update|--update-|--update-h|\
  50        --update-he|--update-hea|--update-head|--update-head-|\
  51        --update-head-o|--update-head-ok)
  52                update_head_ok=t
  53                ;;
  54        -v|--verbose)
  55                verbose=Yes
  56                ;;
  57        -k|--k|--ke|--kee|--keep)
  58                keep='-k -k'
  59                ;;
  60        --depth=*)
  61                shallow_depth="--depth=`expr "z$1" : 'z-[^=]*=\(.*\)'`"
  62                ;;
  63        --depth)
  64                shift
  65                shallow_depth="--depth=$1"
  66                ;;
  67        -*)
  68                usage
  69                ;;
  70        *)
  71                break
  72                ;;
  73        esac
  74        shift
  75done
  76
  77case "$#" in
  780)
  79        origin=$(get_default_remote)
  80        test -n "$(get_remote_url ${origin})" ||
  81                die "Where do you want to fetch from today?"
  82        set x $origin ; shift ;;
  83esac
  84
  85remote_nick="$1"
  86remote=$(get_remote_url "$@")
  87refs=
  88rref=
  89rsync_slurped_objects=
  90
  91if test "" = "$append"
  92then
  93        : >"$GIT_DIR/FETCH_HEAD"
  94fi
  95
  96# Global that is reused later
  97ls_remote_result=$(git ls-remote $upload_pack "$remote") ||
  98        die "Cannot get the repository state from $remote"
  99
 100append_fetch_head () {
 101    head_="$1"
 102    remote_="$2"
 103    remote_name_="$3"
 104    remote_nick_="$4"
 105    local_name_="$5"
 106    case "$6" in
 107    t) not_for_merge_='not-for-merge' ;;
 108    '') not_for_merge_= ;;
 109    esac
 110
 111    # remote-nick is the URL given on the command line (or a shorthand)
 112    # remote-name is the $GIT_DIR relative refs/ path we computed
 113    # for this refspec.
 114
 115    # the $note_ variable will be fed to git-fmt-merge-msg for further
 116    # processing.
 117    case "$remote_name_" in
 118    HEAD)
 119        note_= ;;
 120    refs/heads/*)
 121        note_="$(expr "$remote_name_" : 'refs/heads/\(.*\)')"
 122        note_="branch '$note_' of " ;;
 123    refs/tags/*)
 124        note_="$(expr "$remote_name_" : 'refs/tags/\(.*\)')"
 125        note_="tag '$note_' of " ;;
 126    refs/remotes/*)
 127        note_="$(expr "$remote_name_" : 'refs/remotes/\(.*\)')"
 128        note_="remote branch '$note_' of " ;;
 129    *)
 130        note_="$remote_name of " ;;
 131    esac
 132    remote_1_=$(expr "z$remote_" : 'z\(.*\)\.git/*$') &&
 133        remote_="$remote_1_"
 134    note_="$note_$remote_"
 135
 136    # 2.6.11-tree tag would not be happy to be fed to resolve.
 137    if git-cat-file commit "$head_" >/dev/null 2>&1
 138    then
 139        headc_=$(git-rev-parse --verify "$head_^0") || exit
 140        echo "$headc_   $not_for_merge_ $note_" >>"$GIT_DIR/FETCH_HEAD"
 141    else
 142        echo "$head_    not-for-merge   $note_" >>"$GIT_DIR/FETCH_HEAD"
 143    fi
 144
 145    update_local_ref "$local_name_" "$head_" "$note_"
 146}
 147
 148update_local_ref () {
 149    # If we are storing the head locally make sure that it is
 150    # a fast forward (aka "reverse push").
 151
 152    label_=$(git-cat-file -t $2)
 153    newshort_=$(git-rev-parse --short $2)
 154    if test -z "$1" ; then
 155        [ "$verbose" ] && echo >&2 "* fetched $3"
 156        [ "$verbose" ] && echo >&2 "  $label_: $newshort_"
 157        return 0
 158    fi
 159    oldshort_=$(git show-ref --hash --abbrev "$1" 2>/dev/null)
 160
 161    case "$1" in
 162    refs/tags/*)
 163        # Tags need not be pointing at commits so there
 164        # is no way to guarantee "fast-forward" anyway.
 165        if test -n "$oldshort_"
 166        then
 167                if now_=$(git show-ref --hash "$1") && test "$now_" = "$2"
 168                then
 169                        [ "$verbose" ] && echo >&2 "* $1: same as $3"
 170                        [ "$verbose" ] && echo >&2 "  $label_: $newshort_" ||:
 171                else
 172                        echo >&2 "* $1: updating with $3"
 173                        echo >&2 "  $label_: $newshort_"
 174                        git-update-ref -m "$GIT_REFLOG_ACTION: updating tag" "$1" "$2"
 175                fi
 176        else
 177                echo >&2 "* $1: storing $3"
 178                echo >&2 "  $label_: $newshort_"
 179                git-update-ref -m "$GIT_REFLOG_ACTION: storing tag" "$1" "$2"
 180        fi
 181        ;;
 182
 183    refs/heads/* | refs/remotes/*)
 184        # $1 is the ref being updated.
 185        # $2 is the new value for the ref.
 186        local=$(git-rev-parse --verify "$1^0" 2>/dev/null)
 187        if test "$local"
 188        then
 189            # Require fast-forward.
 190            mb=$(git-merge-base "$local" "$2") &&
 191            case "$2,$mb" in
 192            $local,*)
 193                if test -n "$verbose"
 194                then
 195                        echo >&2 "* $1: same as $3"
 196                        echo >&2 "  $label_: $newshort_"
 197                fi
 198                ;;
 199            *,$local)
 200                echo >&2 "* $1: fast forward to $3"
 201                echo >&2 "  old..new: $oldshort_..$newshort_"
 202                git-update-ref -m "$GIT_REFLOG_ACTION: fast-forward" "$1" "$2" "$local"
 203                ;;
 204            *)
 205                false
 206                ;;
 207            esac || {
 208                case ",$force,$single_force," in
 209                *,t,*)
 210                        echo >&2 "* $1: forcing update to non-fast forward $3"
 211                        echo >&2 "  old...new: $oldshort_...$newshort_"
 212                        git-update-ref -m "$GIT_REFLOG_ACTION: forced-update" "$1" "$2" "$local"
 213                        ;;
 214                *)
 215                        echo >&2 "* $1: not updating to non-fast forward $3"
 216                        echo >&2 "  old...new: $oldshort_...$newshort_"
 217                        exit 1
 218                        ;;
 219                esac
 220            }
 221        else
 222            echo >&2 "* $1: storing $3"
 223            echo >&2 "  $label_: $newshort_"
 224            git-update-ref -m "$GIT_REFLOG_ACTION: storing head" "$1" "$2"
 225        fi
 226        ;;
 227    esac
 228}
 229
 230# updating the current HEAD with git-fetch in a bare
 231# repository is always fine.
 232if test -z "$update_head_ok" && test $(is_bare_repository) = false
 233then
 234        orig_head=$(git-rev-parse --verify HEAD 2>/dev/null)
 235fi
 236
 237# If --tags (and later --heads or --all) is specified, then we are
 238# not talking about defaults stored in Pull: line of remotes or
 239# branches file, and just fetch those and refspecs explicitly given.
 240# Otherwise we do what we always did.
 241
 242reflist=$(get_remote_refs_for_fetch "$@")
 243if test "$tags"
 244then
 245        taglist=`IFS='  ' &&
 246                  echo "$ls_remote_result" |
 247                  while read sha1 name
 248                  do
 249                        case "$sha1" in
 250                        fail)
 251                                exit 1
 252                        esac
 253                        case "$name" in
 254                        *^*) continue ;;
 255                        refs/tags/*) ;;
 256                        *) continue ;;
 257                        esac
 258                        if git-check-ref-format "$name"
 259                        then
 260                            echo ".${name}:${name}"
 261                        else
 262                            echo >&2 "warning: tag ${name} ignored"
 263                        fi
 264                  done` || exit
 265        if test "$#" -gt 1
 266        then
 267                # remote URL plus explicit refspecs; we need to merge them.
 268                reflist="$reflist$LF$taglist"
 269        else
 270                # No explicit refspecs; fetch tags only.
 271                reflist=$taglist
 272        fi
 273fi
 274
 275fetch_main () {
 276  reflist="$1"
 277  refs=
 278  rref=
 279
 280  for ref in $reflist
 281  do
 282      refs="$refs$LF$ref"
 283
 284      # These are relative path from $GIT_DIR, typically starting at refs/
 285      # but may be HEAD
 286      if expr "z$ref" : 'z\.' >/dev/null
 287      then
 288          not_for_merge=t
 289          ref=$(expr "z$ref" : 'z\.\(.*\)')
 290      else
 291          not_for_merge=
 292      fi
 293      if expr "z$ref" : 'z+' >/dev/null
 294      then
 295          single_force=t
 296          ref=$(expr "z$ref" : 'z+\(.*\)')
 297      else
 298          single_force=
 299      fi
 300      remote_name=$(expr "z$ref" : 'z\([^:]*\):')
 301      local_name=$(expr "z$ref" : 'z[^:]*:\(.*\)')
 302
 303      rref="$rref$LF$remote_name"
 304
 305      # There are transports that can fetch only one head at a time...
 306      case "$remote" in
 307      http://* | https://* | ftp://*)
 308          test -n "$shallow_depth" &&
 309                die "shallow clone with http not supported"
 310          proto=`expr "$remote" : '\([^:]*\):'`
 311          if [ -n "$GIT_SSL_NO_VERIFY" ]; then
 312              curl_extra_args="-k"
 313          fi
 314          if [ -n "$GIT_CURL_FTP_NO_EPSV" -o \
 315                "`git-repo-config --bool http.noEPSV`" = true ]; then
 316              noepsv_opt="--disable-epsv"
 317          fi
 318
 319          # Find $remote_name from ls-remote output.
 320          head=$(
 321                IFS='   '
 322                echo "$ls_remote_result" |
 323                while read sha1 name
 324                do
 325                        test "z$name" = "z$remote_name" || continue
 326                        echo "$sha1"
 327                        break
 328                done
 329          )
 330          expr "z$head" : "z$_x40\$" >/dev/null ||
 331                die "No such ref $remote_name at $remote"
 332          echo >&2 "Fetching $remote_name from $remote using $proto"
 333          git-http-fetch -v -a "$head" "$remote/" || exit
 334          ;;
 335      rsync://*)
 336          test -n "$shallow_depth" &&
 337                die "shallow clone with rsync not supported"
 338          TMP_HEAD="$GIT_DIR/TMP_HEAD"
 339          rsync -L -q "$remote/$remote_name" "$TMP_HEAD" || exit 1
 340          head=$(git-rev-parse --verify TMP_HEAD)
 341          rm -f "$TMP_HEAD"
 342          test "$rsync_slurped_objects" || {
 343              rsync -av --ignore-existing --exclude info \
 344                  "$remote/objects/" "$GIT_OBJECT_DIRECTORY/" || exit
 345
 346              # Look at objects/info/alternates for rsync -- http will
 347              # support it natively and git native ones will do it on
 348              # the remote end.  Not having that file is not a crime.
 349              rsync -q "$remote/objects/info/alternates" \
 350                  "$GIT_DIR/TMP_ALT" 2>/dev/null ||
 351                  rm -f "$GIT_DIR/TMP_ALT"
 352              if test -f "$GIT_DIR/TMP_ALT"
 353              then
 354                  resolve_alternates "$remote" <"$GIT_DIR/TMP_ALT" |
 355                  while read alt
 356                  do
 357                      case "$alt" in 'bad alternate: '*) die "$alt";; esac
 358                      echo >&2 "Getting alternate: $alt"
 359                      rsync -av --ignore-existing --exclude info \
 360                      "$alt" "$GIT_OBJECT_DIRECTORY/" || exit
 361                  done
 362                  rm -f "$GIT_DIR/TMP_ALT"
 363              fi
 364              rsync_slurped_objects=t
 365          }
 366          ;;
 367      *)
 368          # We will do git native transport with just one call later.
 369          continue ;;
 370      esac
 371
 372      append_fetch_head "$head" "$remote" \
 373          "$remote_name" "$remote_nick" "$local_name" "$not_for_merge" || exit
 374
 375  done
 376
 377  case "$remote" in
 378  http://* | https://* | ftp://* | rsync://* )
 379      ;; # we are already done.
 380  *)
 381    ( : subshell because we muck with IFS
 382      IFS="     $LF"
 383      (
 384          git-fetch-pack --thin $exec $keep $shallow_depth "$remote" $rref ||
 385          echo failed "$remote"
 386      ) |
 387      (
 388        trap '
 389                if test -n "$keepfile" && test -f "$keepfile"
 390                then
 391                        rm -f "$keepfile"
 392                fi
 393        ' 0
 394
 395        keepfile=
 396        while read sha1 remote_name
 397        do
 398          case "$sha1" in
 399          failed)
 400                  echo >&2 "Fetch failure: $remote"
 401                  exit 1 ;;
 402          # special line coming from index-pack with the pack name
 403          pack)
 404                  continue ;;
 405          keep)
 406                  keepfile="$GIT_OBJECT_DIRECTORY/pack/pack-$remote_name.keep"
 407                  continue ;;
 408          esac
 409          found=
 410          single_force=
 411          for ref in $refs
 412          do
 413              case "$ref" in
 414              +$remote_name:*)
 415                  single_force=t
 416                  not_for_merge=
 417                  found="$ref"
 418                  break ;;
 419              .+$remote_name:*)
 420                  single_force=t
 421                  not_for_merge=t
 422                  found="$ref"
 423                  break ;;
 424              .$remote_name:*)
 425                  not_for_merge=t
 426                  found="$ref"
 427                  break ;;
 428              $remote_name:*)
 429                  not_for_merge=
 430                  found="$ref"
 431                  break ;;
 432              esac
 433          done
 434          local_name=$(expr "z$found" : 'z[^:]*:\(.*\)')
 435          append_fetch_head "$sha1" "$remote" \
 436                  "$remote_name" "$remote_nick" "$local_name" \
 437                  "$not_for_merge" || exit
 438        done
 439      )
 440    ) || exit ;;
 441  esac
 442
 443}
 444
 445fetch_main "$reflist" || exit
 446
 447# automated tag following
 448case "$no_tags$tags" in
 449'')
 450        case "$reflist" in
 451        *:refs/*)
 452                # effective only when we are following remote branch
 453                # using local tracking branch.
 454                taglist=$(IFS=' ' &&
 455                echo "$ls_remote_result" |
 456                git-show-ref --exclude-existing=refs/tags/ |
 457                while read sha1 name
 458                do
 459                        git-cat-file -t "$sha1" >/dev/null 2>&1 || continue
 460                        echo >&2 "Auto-following $name"
 461                        echo ".${name}:${name}"
 462                done)
 463        esac
 464        case "$taglist" in
 465        '') ;;
 466        ?*)
 467                # do not deepen a shallow tree when following tags
 468                shallow_depth=
 469                fetch_main "$taglist" || exit ;;
 470        esac
 471esac
 472
 473# If the original head was empty (i.e. no "master" yet), or
 474# if we were told not to worry, we do not have to check.
 475case "$orig_head" in
 476'')
 477        ;;
 478?*)
 479        curr_head=$(git-rev-parse --verify HEAD 2>/dev/null)
 480        if test "$curr_head" != "$orig_head"
 481        then
 482            git-update-ref \
 483                        -m "$GIT_REFLOG_ACTION: Undoing incorrectly fetched HEAD." \
 484                        HEAD "$orig_head"
 485                die "Cannot fetch into the current branch."
 486        fi
 487        ;;
 488esac