Code

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