[PATCH] New git-apply test cases for scanning forwards and backwards.
[git.git] / git-fetch-script
1 #!/bin/sh
2 #
3 . git-sh-setup-script || die "Not a git archive"
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=
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     # 2.6.11-tree tag would not be happy to be fed to resolve.
59     if git-cat-file commit "$head_" >/dev/null 2>&1
60     then
61         headc_=$(git-rev-parse --verify "$head_^0") || exit
62         note_="$headc_  $remote_name_ from $remote_nick_"
63         echo "$note_" >>$GIT_DIR/FETCH_HEAD
64         echo >&2 "* committish: $note_"
65     else
66         echo >&2 "* non-commit: $note_"
67     fi
68     if test "$local_name_" != ""
69     then
70         # We are storing the head locally.  Make sure that it is
71         # a fast forward (aka "reverse push").
72         fast_forward_local "$local_name_" "$head_" "$remote_" "$remote_name_"
73     fi
74 }
75
76 fast_forward_local () {
77     case "$1" in
78     refs/tags/*)
79         # Tags need not be pointing at commits so there
80         # is no way to guarantee "fast-forward" anyway.
81         if test -f "$GIT_DIR/$1"
82         then
83                 echo >&2 "* $1: updating with $4"
84                 echo >&2 "  from $3."
85         else
86                 echo >&2 "* $1: storing $4"
87                 echo >&2 "  from $3."
88         fi
89         echo "$2" >"$GIT_DIR/$1" ;;
90
91     refs/heads/*)
92         # NEEDSWORK: use the same cmpxchg protocol here.
93         echo "$2" >"$GIT_DIR/$1.lock"
94         if test -f "$GIT_DIR/$1"
95         then
96             local=$(git-rev-parse --verify "$1^0") &&
97             mb=$(git-merge-base "$local" "$2") &&
98             case "$2,$mb" in
99             $local,*)
100                 echo >&2 "* $1: same as $4"
101                 echo >&2 "  from $3"
102                 ;;
103             *,$local)
104                 echo >&2 "* $1: fast forward to $4"
105                 echo >&2 "  from $3"
106                 ;;
107             *)
108                 false
109                 ;;
110             esac || {
111                 echo >&2 "* $1: does not fast forward to $4"
112                 case "$force,$single_force" in
113                 t,* | *,t)
114                         echo >&2 "  from $3; forcing update."
115                         ;;
116                 *)
117                         mv "$GIT_DIR/$1.lock" "$GIT_DIR/$1.remote"
118                         echo >&2 "  from $3; leaving it in '$1.remote'"
119                         ;;
120                 esac
121             }
122         else
123                 echo >&2 "* $1: storing $4"
124                 echo >&2 "  from $3."
125         fi
126         test -f "$GIT_DIR/$1.lock" &&
127             mv "$GIT_DIR/$1.lock" "$GIT_DIR/$1"
128         ;;
129     esac
130 }
131
132 case "$update_head_ok" in
133 '')
134         orig_head=$(cat "$GIT_DIR/HEAD" 2>/dev/null)
135         ;;
136 esac
137
138 for ref in $(get_remote_refs_for_fetch "$@")
139 do
140     refs="$refs $ref"
141
142     # These are relative path from $GIT_DIR, typically starting at refs/
143     # but may be HEAD
144     if expr "$ref" : '\+' >/dev/null
145     then
146         single_force=t
147         ref=$(expr "$ref" : '\+\(.*\)')
148     else
149         single_force=
150     fi
151     remote_name=$(expr "$ref" : '\([^:]*\):')
152     local_name=$(expr "$ref" : '[^:]*:\(.*\)')
153
154     rref="$rref $remote_name"
155
156     # There are transports that can fetch only one head at a time...
157     case "$remote" in
158     http://* | https://*)
159         if [ -n "$GIT_SSL_NO_VERIFY" ]; then
160             curl_extra_args="-k"
161         fi
162         head=$(curl -nsf $curl_extra_args "$remote/$remote_name") &&
163         expr "$head" : "$_x40\$" >/dev/null ||
164                 die "Failed to fetch $remote_name from $remote"
165         echo Fetching "$remote_name from $remote" using http
166         git-http-pull -v -a "$head" "$remote/" || exit
167         ;;
168     rsync://*)
169         TMP_HEAD="$GIT_DIR/TMP_HEAD"
170         rsync -L "$remote/$remote_name" "$TMP_HEAD" || exit 1
171         head=$(git-rev-parse TMP_HEAD)
172         rm -f "$TMP_HEAD"
173         test "$rsync_slurped_objects" || {
174             rsync -avz --ignore-existing "$remote/objects/" \
175                 "$GIT_OBJECT_DIRECTORY/" || exit
176             rsync_slurped_objects=t
177         }
178         ;;
179     *)
180         # We will do git native transport with just one call later.
181         continue ;;
182     esac
183
184     append_fetch_head "$head" "$remote" "$remote_name" "$remote_nick" "$local_name"
185
186 done
187
188 case "$remote" in
189 http://* | https://* | rsync://* )
190     ;; # we are already done.
191 *)
192     git-fetch-pack "$remote" $rref |
193     while read sha1 remote_name
194     do
195         found=
196         single_force=
197         for ref in $refs
198         do
199             case "$ref" in
200             +$remote_name:*)
201                 single_force=t
202                 found="$ref"
203                 break ;;
204             $remote_name:*)
205                 found="$ref"
206                 break ;;
207             esac
208         done
209
210         local_name=$(expr "$found" : '[^:]*:\(.*\)')
211         append_fetch_head "$sha1" "$remote" "$remote_name" "$remote_nick" "$local_name"
212     done
213     ;;
214 esac
215
216 # If the original head was empty (i.e. no "master" yet), or
217 # if we were told not to worry, we do not have to check.
218 case ",$update_head_ok,$orig_head," in
219 *,, | t,* )
220         ;;
221 *)
222         curr_head=$(cat "$GIT_DIR/HEAD" 2>/dev/null)
223         if test "$curr_head" != "$orig_head"
224         then
225                 echo "$orig_head" >$GIT_DIR/HEAD
226                 die "Cannot fetch into the current branch."
227         fi
228         ;;
229 esac