]>
Commit | Line | Data |
---|---|---|
7ef76925 LT |
1 | #!/bin/sh |
2 | # | |
b33e9666 | 3 | . git-sh-setup-script || die "Not a git archive" |
853a3697 JH |
4 | . git-parse-remote-script |
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 | ||
8 | append= | |
ae2da406 | 9 | force= |
b10ac50f | 10 | update_head_ok= |
ae2da406 JH |
11 | while case "$#" in 0) break ;; esac |
12 | do | |
13 | case "$1" in | |
14 | -a|--a|--ap|--app|--appe|--appen|--append) | |
15 | append=t | |
ae2da406 JH |
16 | ;; |
17 | -f|--f|--fo|--for|--forc|--force) | |
18 | force=t | |
b10ac50f JH |
19 | ;; |
20 | -u|--u|--up|--upd|--upda|--updat|--update|--update-|--update-h|\ | |
21 | --update-he|--update-hea|--update-head|--update-head-|\ | |
22 | --update-head-o|--update-head-ok) | |
23 | update_head_ok=t | |
ae2da406 JH |
24 | ;; |
25 | *) | |
26 | break | |
27 | ;; | |
28 | esac | |
b10ac50f | 29 | shift |
ae2da406 JH |
30 | done |
31 | ||
853a3697 JH |
32 | case "$#" in |
33 | 0) | |
92c533ef JH |
34 | test -f "$GIT_DIR/branches/origin" || |
35 | test -f "$GIT_DIR/remotes/origin" || | |
b10ac50f | 36 | die "Where do you want to fetch from today?" |
92c533ef | 37 | set origin ;; |
853a3697 | 38 | esac |
ae2da406 | 39 | |
853a3697 JH |
40 | remote_nick="$1" |
41 | remote=$(get_remote_url "$@") | |
42 | refs= | |
43 | rref= | |
44 | rsync_slurped_objects= | |
45 | ||
46 | if test "" = "$append" | |
47 | then | |
48 | : >$GIT_DIR/FETCH_HEAD | |
49 | fi | |
50 | ||
51 | append_fetch_head () { | |
52 | head_="$1" | |
53 | remote_="$2" | |
54 | remote_name_="$3" | |
55 | remote_nick_="$4" | |
56 | local_name_="$5" | |
57 | ||
06ec2b4b JH |
58 | # remote-nick is the URL given on the command line (or a shorthand) |
59 | # remote-name is the $GIT_DIR relative refs/ path we computed | |
60 | # for this refspec. | |
61 | case "$remote_name_" in | |
62 | HEAD) | |
63 | note_= ;; | |
64 | refs/heads/*) | |
65 | note_="$(expr "$remote_name_" : 'refs/heads/\(.*\)')" | |
66 | note_="branch '$note_' of " ;; | |
67 | refs/tags/*) | |
68 | note_="$(expr "$remote_name_" : 'refs/tags/\(.*\)')" | |
69 | note_="tag '$note_' of " ;; | |
70 | *) | |
71 | note_="$remote_name of " ;; | |
72 | esac | |
73 | remote_1_=$(expr "$remote_" : '\(.*\)\.git/*$') && | |
74 | remote_="$remote_1_" | |
75 | note_="$note_$remote_" | |
76 | ||
853a3697 JH |
77 | # 2.6.11-tree tag would not be happy to be fed to resolve. |
78 | if git-cat-file commit "$head_" >/dev/null 2>&1 | |
79 | then | |
8572aa85 | 80 | headc_=$(git-rev-parse --verify "$head_^0") || exit |
06ec2b4b JH |
81 | echo "$headc_ $note_" >>$GIT_DIR/FETCH_HEAD |
82 | echo >&2 "* committish: $head_" | |
83 | echo >&2 " $note_" | |
853a3697 | 84 | else |
06ec2b4b JH |
85 | echo >&2 "* non-commit: $head_" |
86 | echo >&2 " $note_" | |
853a3697 JH |
87 | fi |
88 | if test "$local_name_" != "" | |
89 | then | |
90 | # We are storing the head locally. Make sure that it is | |
91 | # a fast forward (aka "reverse push"). | |
06ec2b4b | 92 | fast_forward_local "$local_name_" "$head_" "$note_" |
853a3697 JH |
93 | fi |
94 | } | |
95 | ||
96 | fast_forward_local () { | |
97 | case "$1" in | |
98 | refs/tags/*) | |
99 | # Tags need not be pointing at commits so there | |
100 | # is no way to guarantee "fast-forward" anyway. | |
ae2da406 JH |
101 | if test -f "$GIT_DIR/$1" |
102 | then | |
06ec2b4b | 103 | echo >&2 "* $1: updating with $3" |
ae2da406 | 104 | else |
06ec2b4b | 105 | echo >&2 "* $1: storing $3" |
ae2da406 | 106 | fi |
853a3697 | 107 | echo "$2" >"$GIT_DIR/$1" ;; |
ae2da406 | 108 | |
853a3697 JH |
109 | refs/heads/*) |
110 | # NEEDSWORK: use the same cmpxchg protocol here. | |
111 | echo "$2" >"$GIT_DIR/$1.lock" | |
112 | if test -f "$GIT_DIR/$1" | |
33b83034 | 113 | then |
853a3697 JH |
114 | local=$(git-rev-parse --verify "$1^0") && |
115 | mb=$(git-merge-base "$local" "$2") && | |
116 | case "$2,$mb" in | |
117 | $local,*) | |
06ec2b4b | 118 | echo >&2 "* $1: same as $3" |
853a3697 JH |
119 | ;; |
120 | *,$local) | |
06ec2b4b | 121 | echo >&2 "* $1: fast forward to $3" |
853a3697 JH |
122 | ;; |
123 | *) | |
124 | false | |
125 | ;; | |
126 | esac || { | |
06ec2b4b | 127 | echo >&2 "* $1: does not fast forward to $3;" |
efe9bf0f JH |
128 | case "$force,$single_force" in |
129 | t,* | *,t) | |
06ec2b4b | 130 | echo >&2 " forcing update." |
ae2da406 JH |
131 | ;; |
132 | *) | |
133 | mv "$GIT_DIR/$1.lock" "$GIT_DIR/$1.remote" | |
06ec2b4b | 134 | echo >&2 " leaving it in '$1.remote'" |
ae2da406 JH |
135 | ;; |
136 | esac | |
853a3697 JH |
137 | } |
138 | else | |
06ec2b4b | 139 | echo >&2 "* $1: storing $3" |
33b83034 | 140 | fi |
853a3697 JH |
141 | test -f "$GIT_DIR/$1.lock" && |
142 | mv "$GIT_DIR/$1.lock" "$GIT_DIR/$1" | |
0a623e7c | 143 | ;; |
853a3697 JH |
144 | esac |
145 | } | |
146 | ||
b10ac50f JH |
147 | case "$update_head_ok" in |
148 | '') | |
149 | orig_head=$(cat "$GIT_DIR/HEAD" 2>/dev/null) | |
150 | ;; | |
151 | esac | |
152 | ||
853a3697 JH |
153 | for ref in $(get_remote_refs_for_fetch "$@") |
154 | do | |
155 | refs="$refs $ref" | |
f170e4b3 | 156 | |
853a3697 JH |
157 | # These are relative path from $GIT_DIR, typically starting at refs/ |
158 | # but may be HEAD | |
efe9bf0f JH |
159 | if expr "$ref" : '\+' >/dev/null |
160 | then | |
161 | single_force=t | |
162 | ref=$(expr "$ref" : '\+\(.*\)') | |
163 | else | |
164 | single_force= | |
165 | fi | |
853a3697 JH |
166 | remote_name=$(expr "$ref" : '\([^:]*\):') |
167 | local_name=$(expr "$ref" : '[^:]*:\(.*\)') | |
f170e4b3 | 168 | |
853a3697 JH |
169 | rref="$rref $remote_name" |
170 | ||
171 | # There are transports that can fetch only one head at a time... | |
172 | case "$remote" in | |
173 | http://* | https://*) | |
174 | if [ -n "$GIT_SSL_NO_VERIFY" ]; then | |
175 | curl_extra_args="-k" | |
176 | fi | |
177 | head=$(curl -nsf $curl_extra_args "$remote/$remote_name") && | |
178 | expr "$head" : "$_x40\$" >/dev/null || | |
b10ac50f | 179 | die "Failed to fetch $remote_name from $remote" |
853a3697 JH |
180 | echo Fetching "$remote_name from $remote" using http |
181 | git-http-pull -v -a "$head" "$remote/" || exit | |
60ea0fdd | 182 | ;; |
853a3697 JH |
183 | rsync://*) |
184 | TMP_HEAD="$GIT_DIR/TMP_HEAD" | |
185 | rsync -L "$remote/$remote_name" "$TMP_HEAD" || exit 1 | |
186 | head=$(git-rev-parse TMP_HEAD) | |
187 | rm -f "$TMP_HEAD" | |
188 | test "$rsync_slurped_objects" || { | |
189 | rsync -avz --ignore-existing "$remote/objects/" \ | |
190 | "$GIT_OBJECT_DIRECTORY/" || exit | |
191 | rsync_slurped_objects=t | |
192 | } | |
193 | ;; | |
194 | *) | |
195 | # We will do git native transport with just one call later. | |
196 | continue ;; | |
197 | esac | |
198 | ||
199 | append_fetch_head "$head" "$remote" "$remote_name" "$remote_nick" "$local_name" | |
f170e4b3 | 200 | |
853a3697 JH |
201 | done |
202 | ||
203 | case "$remote" in | |
204 | http://* | https://* | rsync://* ) | |
205 | ;; # we are already done. | |
206 | *) | |
207 | git-fetch-pack "$remote" $rref | | |
208 | while read sha1 remote_name | |
209 | do | |
210 | found= | |
efe9bf0f | 211 | single_force= |
853a3697 JH |
212 | for ref in $refs |
213 | do | |
214 | case "$ref" in | |
efe9bf0f JH |
215 | +$remote_name:*) |
216 | single_force=t | |
217 | found="$ref" | |
218 | break ;; | |
853a3697 JH |
219 | $remote_name:*) |
220 | found="$ref" | |
221 | break ;; | |
222 | esac | |
223 | done | |
f170e4b3 | 224 | |
853a3697 | 225 | local_name=$(expr "$found" : '[^:]*:\(.*\)') |
efe9bf0f | 226 | append_fetch_head "$sha1" "$remote" "$remote_name" "$remote_nick" "$local_name" |
853a3697 JH |
227 | done |
228 | ;; | |
229 | esac | |
b10ac50f JH |
230 | |
231 | # If the original head was empty (i.e. no "master" yet), or | |
232 | # if we were told not to worry, we do not have to check. | |
233 | case ",$update_head_ok,$orig_head," in | |
234 | *,, | t,* ) | |
235 | ;; | |
236 | *) | |
237 | curr_head=$(cat "$GIT_DIR/HEAD" 2>/dev/null) | |
238 | if test "$curr_head" != "$orig_head" | |
239 | then | |
240 | echo "$orig_head" >$GIT_DIR/HEAD | |
241 | die "Cannot fetch into the current branch." | |
242 | fi | |
243 | ;; | |
244 | esac |