[PATCH] Documentation/repository-layout.txt typo
[git.git] / git-fetch.sh
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
8 append=
9 force=
10 update_head_ok=
11 while case "$#" in 0) break ;; esac
12 do
13         case "$1" in
14         -a|--a|--ap|--app|--appe|--appen|--append)
15                 append=t
16                 ;;
17         -f|--f|--fo|--for|--forc|--force)
18                 force=t
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
24                 ;;
25         *)
26                 break
27                 ;;
28         esac
29         shift
30 done
31
32 case "$#" in
33 0)
34         test -f "$GIT_DIR/branches/origin" ||
35                 test -f "$GIT_DIR/remotes/origin" ||
36                         die "Where do you want to fetch from today?"
37         set origin ;;
38 esac
39
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
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
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
80         headc_=$(git-rev-parse --verify "$head_^0") || exit
81         echo "$headc_   $note_" >>$GIT_DIR/FETCH_HEAD
82         echo >&2 "* committish: $head_"
83         echo >&2 "  $note_"
84     else
85         echo >&2 "* non-commit: $head_"
86         echo >&2 "  $note_"
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").
92         fast_forward_local "$local_name_" "$head_" "$note_"
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.
101         if test -f "$GIT_DIR/$1"
102         then
103                 echo >&2 "* $1: updating with $3"
104         else
105                 echo >&2 "* $1: storing $3"
106         fi
107         echo "$2" >"$GIT_DIR/$1" ;;
108
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"
113         then
114             local=$(git-rev-parse --verify "$1^0") &&
115             mb=$(git-merge-base "$local" "$2") &&
116             case "$2,$mb" in
117             $local,*)
118                 echo >&2 "* $1: same as $3"
119                 ;;
120             *,$local)
121                 echo >&2 "* $1: fast forward to $3"
122                 ;;
123             *)
124                 false
125                 ;;
126             esac || {
127                 echo >&2 "* $1: does not fast forward to $3;"
128                 case "$force,$single_force" in
129                 t,* | *,t)
130                         echo >&2 "  forcing update."
131                         ;;
132                 *)
133                         mv "$GIT_DIR/$1.lock" "$GIT_DIR/$1.remote"
134                         echo >&2 "  leaving it in '$1.remote'"
135                         ;;
136                 esac
137             }
138         else
139                 echo >&2 "* $1: storing $3"
140         fi
141         test -f "$GIT_DIR/$1.lock" &&
142             mv "$GIT_DIR/$1.lock" "$GIT_DIR/$1"
143         ;;
144     esac
145 }
146
147 case "$update_head_ok" in
148 '')
149         orig_head=$(cat "$GIT_DIR/HEAD" 2>/dev/null)
150         ;;
151 esac
152
153 for ref in $(get_remote_refs_for_fetch "$@")
154 do
155     refs="$refs $ref"
156
157     # These are relative path from $GIT_DIR, typically starting at refs/
158     # but may be HEAD
159     if expr "$ref" : '\+' >/dev/null
160     then
161         single_force=t
162         ref=$(expr "$ref" : '\+\(.*\)')
163     else
164         single_force=
165     fi
166     remote_name=$(expr "$ref" : '\([^:]*\):')
167     local_name=$(expr "$ref" : '[^:]*:\(.*\)')
168
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 ||
179                 die "Failed to fetch $remote_name from $remote"
180         echo Fetching "$remote_name from $remote" using http
181         git-http-fetch -v -a "$head" "$remote/" || exit
182         ;;
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"
200
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=
211         single_force=
212         for ref in $refs
213         do
214             case "$ref" in
215             +$remote_name:*)
216                 single_force=t
217                 found="$ref"
218                 break ;;
219             $remote_name:*)
220                 found="$ref"
221                 break ;;
222             esac
223         done
224
225         local_name=$(expr "$found" : '[^:]*:\(.*\)')
226         append_fetch_head "$sha1" "$remote" "$remote_name" "$remote_nick" "$local_name"
227     done
228     ;;
229 esac
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