1#!/bin/sh 2# 3. git-sh-setup || die "Not a git archive" 4. git-parse-remote 5_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' 6_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40" 7 8tags= 9append= 10force= 11update_head_ok= 12while case"$#"in0)break;;esac 13do 14case"$1"in 15-a|--a|--ap|--app|--appe|--appen|--append) 16 append=t 17;; 18-f|--f|--fo|--for|--forc|--force) 19 force=t 20;; 21-t|--t|--ta|--tag|--tags) 22 tags=t 23;; 24-u|--u|--up|--upd|--upda|--updat|--update|--update-|--update-h|\ 25--update-he|--update-hea|--update-head|--update-head-|\ 26--update-head-o|--update-head-ok) 27 update_head_ok=t 28;; 29*) 30break 31;; 32esac 33shift 34done 35 36case"$#"in 370) 38test -f"$GIT_DIR/branches/origin"|| 39test -f"$GIT_DIR/remotes/origin"|| 40 die "Where do you want to fetch from today?" 41set origin ;; 42esac 43 44remote_nick="$1" 45remote=$(get_remote_url "$@") 46refs= 47rref= 48rsync_slurped_objects= 49 50iftest""="$append" 51then 52: >"$GIT_DIR/FETCH_HEAD" 53fi 54 55append_fetch_head () { 56 head_="$1" 57 remote_="$2" 58 remote_name_="$3" 59 remote_nick_="$4" 60 local_name_="$5" 61case"$6"in 62 t) not_for_merge_='not-for-merge';; 63'') not_for_merge_= ;; 64esac 65 66# remote-nick is the URL given on the command line (or a shorthand) 67# remote-name is the $GIT_DIR relative refs/ path we computed 68# for this refspec. 69case"$remote_name_"in 70 HEAD) 71 note_= ;; 72 refs/heads/*) 73 note_="$(expr "$remote_name_" : 'refs/heads/\(.*\)')" 74 note_="branch '$note_' of ";; 75 refs/tags/*) 76 note_="$(expr "$remote_name_" : 'refs/tags/\(.*\)')" 77 note_="tag '$note_' of ";; 78*) 79 note_="$remote_nameof ";; 80esac 81 remote_1_=$(expr"$remote_":'\(.*\)\.git/*$') && 82 remote_="$remote_1_" 83 note_="$note_$remote_" 84 85# 2.6.11-tree tag would not be happy to be fed to resolve. 86if git-cat-file commit "$head_">/dev/null 2>&1 87then 88 headc_=$(git-rev-parse --verify"$head_^0") ||exit 89echo"$headc_$not_for_merge_$note_">>"$GIT_DIR/FETCH_HEAD" 90echo>&2"* committish:$head_" 91echo>&2"$note_" 92else 93echo"$head_not-for-merge$note_">>"$GIT_DIR/FETCH_HEAD" 94echo>&2"* non-commit:$head_" 95echo>&2"$note_" 96fi 97iftest"$local_name_"!="" 98then 99# We are storing the head locally. Make sure that it is 100# a fast forward (aka "reverse push"). 101 fast_forward_local "$local_name_""$head_""$note_" 102fi 103} 104 105fast_forward_local () { 106mkdir-p"$(dirname "$GIT_DIR/$1")" 107case"$1"in 108 refs/tags/*) 109# Tags need not be pointing at commits so there 110# is no way to guarantee "fast-forward" anyway. 111iftest -f"$GIT_DIR/$1" 112then 113echo>&2"*$1: updating with$3" 114else 115echo>&2"*$1: storing$3" 116fi 117 git-update-ref "$1""$2" 118;; 119 120 refs/heads/*) 121# $1 is the ref being updated. 122# $2 is the new value for the ref. 123local=$(git-rev-parse --verify"$1^0"2>/dev/null) 124iftest"$local" 125then 126# Require fast-forward. 127 mb=$(git-merge-base "$local""$2") && 128case"$2,$mb"in 129$local,*) 130echo>&2"*$1: same as$3" 131;; 132*,$local) 133echo>&2"*$1: fast forward to$3" 134 git-update-ref "$1""$2""$local" 135;; 136*) 137 false 138;; 139esac|| { 140echo>&2"*$1: does not fast forward to$3;" 141case",$force,$single_force,"in 142*,t,*) 143echo>&2" forcing update." 144 git-update-ref "$1""$2""$local" 145;; 146*) 147echo>&2" not updating." 148;; 149esac 150} 151else 152echo>&2"*$1: storing$3" 153 git-update-ref "$1""$2" 154fi 155;; 156esac 157} 158 159case"$update_head_ok"in 160'') 161 orig_head=$(git-rev-parse --verify HEAD 2>/dev/null) 162;; 163esac 164 165# If --tags (and later --heads or --all) is specified, then we are 166# not talking about defaults stored in Pull: line of remotes or 167# branches file, and just fetch those and refspecs explicitly given. 168# Otherwise we do what we always did. 169 170reflist=$(get_remote_refs_for_fetch "$@") 171iftest"$tags" 172then 173 taglist=$(git-ls-remote --tags"$remote"|awk'{ print "."$2":"$2}') 174iftest"$#"-gt1 175then 176# remote URL plus explicit refspecs; we need to merge them. 177 reflist="$reflist$taglist" 178else 179# No explicit refspecs; fetch tags only. 180 reflist=$taglist 181fi 182fi 183 184for ref in$reflist 185do 186 refs="$refs$ref" 187 188# These are relative path from $GIT_DIR, typically starting at refs/ 189# but may be HEAD 190ifexpr"$ref":'\.'>/dev/null 191then 192 not_for_merge=t 193 ref=$(expr"$ref":'\.\(.*\)') 194else 195 not_for_merge= 196fi 197ifexpr"$ref":'\+'>/dev/null 198then 199 single_force=t 200 ref=$(expr"$ref":'\+\(.*\)') 201else 202 single_force= 203fi 204 remote_name=$(expr"$ref":'\([^:]*\):') 205 local_name=$(expr"$ref":'[^:]*:\(.*\)') 206 207 rref="$rref$remote_name" 208 209# There are transports that can fetch only one head at a time... 210case"$remote"in 211 http://* | https://*) 212if[-n"$GIT_SSL_NO_VERIFY"];then 213 curl_extra_args="-k" 214fi 215head=$(curl -nsf$curl_extra_args"$remote/$remote_name") && 216expr"$head":"$_x40\$">/dev/null || 217 die "Failed to fetch$remote_namefrom$remote" 218echo>&2 Fetching "$remote_namefrom$remote" using http 219 git-http-fetch -v -a"$head""$remote/"||exit 220;; 221 rsync://*) 222 TMP_HEAD="$GIT_DIR/TMP_HEAD" 223 rsync -L -q"$remote/$remote_name""$TMP_HEAD"||exit1 224head=$(git-rev-parse --verify TMP_HEAD) 225rm-f"$TMP_HEAD" 226test"$rsync_slurped_objects"|| { 227 rsync -av --ignore-existing --exclude info \ 228"$remote/objects/""$GIT_OBJECT_DIRECTORY/"||exit 229 230# Look at objects/info/alternates for rsync -- http will 231# support it natively and git native ones will do it on the remote 232# end. Not having that file is not a crime. 233 rsync -q"$remote/objects/info/alternates" \ 234"$GIT_DIR/TMP_ALT"2>/dev/null || 235rm-f"$GIT_DIR/TMP_ALT" 236iftest -f"$GIT_DIR/TMP_ALT" 237then 238 resolve_alternates "$remote"<"$GIT_DIR/TMP_ALT"| 239whileread alt 240do 241case"$alt"in'bad alternate: '*) die "$alt";;esac 242echo>&2"Getting alternate:$alt" 243 rsync -av --ignore-existing --exclude info \ 244"$alt""$GIT_OBJECT_DIRECTORY/"||exit 245done 246rm-f"$GIT_DIR/TMP_ALT" 247fi 248 rsync_slurped_objects=t 249} 250;; 251*) 252# We will do git native transport with just one call later. 253continue;; 254esac 255 256 append_fetch_head "$head""$remote" \ 257"$remote_name""$remote_nick""$local_name""$not_for_merge" 258 259done 260 261case"$remote"in 262http://* | https://* | rsync://* ) 263;;# we are already done. 264*) 265( 266 git-fetch-pack "$remote"$rref||echo failed "$remote" 267) | 268whileread sha1 remote_name 269do 270case"$sha1"in 271 failed) 272echo>&2"Fetch failure:$remote" 273exit1;; 274esac 275 found= 276 single_force= 277for ref in$refs 278do 279case"$ref"in 280+$remote_name:*) 281 single_force=t 282 not_for_merge= 283 found="$ref" 284break;; 285 .+$remote_name:*) 286 single_force=t 287 not_for_merge=t 288 found="$ref" 289break;; 290 .$remote_name:*) 291 not_for_merge=t 292 found="$ref" 293break;; 294$remote_name:*) 295 not_for_merge= 296 found="$ref" 297break;; 298esac 299done 300 local_name=$(expr"$found":'[^:]*:\(.*\)') 301 append_fetch_head "$sha1""$remote" \ 302"$remote_name""$remote_nick""$local_name""$not_for_merge" 303done||exit 304;; 305esac 306 307# If the original head was empty (i.e. no "master" yet), or 308# if we were told not to worry, we do not have to check. 309case",$update_head_ok,$orig_head,"in 310*,, | t,* ) 311;; 312*) 313 curr_head=$(git-rev-parse --verify HEAD 2>/dev/null) 314iftest"$curr_head"!="$orig_head" 315then 316 git-update-ref HEAD "$orig_head" 317 die "Cannot fetch into the current branch." 318fi 319;; 320esac