Merge branch 'rs/allocate-cache-entry-individually'
[git] / t / t5510-fetch.sh
1 #!/bin/sh
2 # Copyright (c) 2006, Junio C Hamano.
3
4 test_description='Per branch config variables affects "git fetch".
5
6 '
7
8 . ./test-lib.sh
9
10 D=`pwd`
11
12 test_bundle_object_count () {
13         git verify-pack -v "$1" >verify.out &&
14         test "$2" = $(grep '^[0-9a-f]\{40\} ' verify.out | wc -l)
15 }
16
17 test_expect_success setup '
18         echo >file original &&
19         git add file &&
20         git commit -a -m original'
21
22 test_expect_success "clone and setup child repos" '
23         git clone . one &&
24         (
25                 cd one &&
26                 echo >file updated by one &&
27                 git commit -a -m "updated by one"
28         ) &&
29         git clone . two &&
30         (
31                 cd two &&
32                 git config branch.master.remote one &&
33                 git config remote.one.url ../one/.git/ &&
34                 git config remote.one.fetch refs/heads/master:refs/heads/one
35         ) &&
36         git clone . three &&
37         (
38                 cd three &&
39                 git config branch.master.remote two &&
40                 git config branch.master.merge refs/heads/one &&
41                 mkdir -p .git/remotes &&
42                 {
43                         echo "URL: ../two/.git/"
44                         echo "Pull: refs/heads/master:refs/heads/two"
45                         echo "Pull: refs/heads/one:refs/heads/one"
46                 } >.git/remotes/two
47         ) &&
48         git clone . bundle &&
49         git clone . seven
50 '
51
52 test_expect_success "fetch test" '
53         cd "$D" &&
54         echo >file updated by origin &&
55         git commit -a -m "updated by origin" &&
56         cd two &&
57         git fetch &&
58         test -f .git/refs/heads/one &&
59         mine=`git rev-parse refs/heads/one` &&
60         his=`cd ../one && git rev-parse refs/heads/master` &&
61         test "z$mine" = "z$his"
62 '
63
64 test_expect_success "fetch test for-merge" '
65         cd "$D" &&
66         cd three &&
67         git fetch &&
68         test -f .git/refs/heads/two &&
69         test -f .git/refs/heads/one &&
70         master_in_two=`cd ../two && git rev-parse master` &&
71         one_in_two=`cd ../two && git rev-parse one` &&
72         {
73                 echo "$master_in_two    not-for-merge"
74                 echo "$one_in_two       "
75         } >expected &&
76         cut -f -2 .git/FETCH_HEAD >actual &&
77         test_cmp expected actual'
78
79 test_expect_success 'fetch --prune on its own works as expected' '
80         cd "$D" &&
81         git clone . prune &&
82         cd prune &&
83         git fetch origin refs/heads/master:refs/remotes/origin/extrabranch &&
84
85         git fetch --prune origin &&
86         test_must_fail git rev-parse origin/extrabranch
87 '
88
89 test_expect_success 'fetch --prune with a branch name keeps branches' '
90         cd "$D" &&
91         git clone . prune-branch &&
92         cd prune-branch &&
93         git fetch origin refs/heads/master:refs/remotes/origin/extrabranch &&
94
95         git fetch --prune origin master &&
96         git rev-parse origin/extrabranch
97 '
98
99 test_expect_success 'fetch --prune with a namespace keeps other namespaces' '
100         cd "$D" &&
101         git clone . prune-namespace &&
102         cd prune-namespace &&
103
104         git fetch --prune origin refs/heads/a/*:refs/remotes/origin/a/* &&
105         git rev-parse origin/master
106 '
107
108 test_expect_success 'fetch --prune --tags does not delete the remote-tracking branches' '
109         cd "$D" &&
110         git clone . prune-tags &&
111         cd prune-tags &&
112         git fetch origin refs/heads/master:refs/tags/sometag &&
113
114         git fetch --prune --tags origin &&
115         git rev-parse origin/master &&
116         test_must_fail git rev-parse somebranch
117 '
118
119 test_expect_success 'fetch --prune --tags with branch does not delete other remote-tracking branches' '
120         cd "$D" &&
121         git clone . prune-tags-branch &&
122         cd prune-tags-branch &&
123         git fetch origin refs/heads/master:refs/remotes/origin/extrabranch &&
124
125         git fetch --prune --tags origin master &&
126         git rev-parse origin/extrabranch
127 '
128
129 test_expect_success 'fetch tags when there is no tags' '
130
131     cd "$D" &&
132
133     mkdir notags &&
134     cd notags &&
135     git init &&
136
137     git fetch -t ..
138
139 '
140
141 test_expect_success 'fetch following tags' '
142
143         cd "$D" &&
144         git tag -a -m 'annotated' anno HEAD &&
145         git tag light HEAD &&
146
147         mkdir four &&
148         cd four &&
149         git init &&
150
151         git fetch .. :track &&
152         git show-ref --verify refs/tags/anno &&
153         git show-ref --verify refs/tags/light
154
155 '
156
157 test_expect_success 'fetch must not resolve short tag name' '
158
159         cd "$D" &&
160
161         mkdir five &&
162         cd five &&
163         git init &&
164
165         test_must_fail git fetch .. anno:five
166
167 '
168
169 test_expect_success 'fetch must not resolve short remote name' '
170
171         cd "$D" &&
172         git update-ref refs/remotes/six/HEAD HEAD &&
173
174         mkdir six &&
175         cd six &&
176         git init &&
177
178         test_must_fail git fetch .. six:six
179
180 '
181
182 test_expect_success 'create bundle 1' '
183         cd "$D" &&
184         echo >file updated again by origin &&
185         git commit -a -m "tip" &&
186         git bundle create bundle1 master^..master
187 '
188
189 test_expect_success 'header of bundle looks right' '
190         head -n 1 "$D"/bundle1 | grep "^#" &&
191         head -n 2 "$D"/bundle1 | grep "^-[0-9a-f]\{40\} " &&
192         head -n 3 "$D"/bundle1 | grep "^[0-9a-f]\{40\} " &&
193         head -n 4 "$D"/bundle1 | grep "^$"
194 '
195
196 test_expect_success 'create bundle 2' '
197         cd "$D" &&
198         git bundle create bundle2 master~2..master
199 '
200
201 test_expect_success 'unbundle 1' '
202         cd "$D/bundle" &&
203         git checkout -b some-branch &&
204         test_must_fail git fetch "$D/bundle1" master:master
205 '
206
207
208 test_expect_success 'bundle 1 has only 3 files ' '
209         cd "$D" &&
210         (
211                 while read x && test -n "$x"
212                 do
213                         :;
214                 done
215                 cat
216         ) <bundle1 >bundle.pack &&
217         git index-pack bundle.pack &&
218         test_bundle_object_count bundle.pack 3
219 '
220
221 test_expect_success 'unbundle 2' '
222         cd "$D/bundle" &&
223         git fetch ../bundle2 master:master &&
224         test "tip" = "$(git log -1 --pretty=oneline master | cut -b42-)"
225 '
226
227 test_expect_success 'bundle does not prerequisite objects' '
228         cd "$D" &&
229         touch file2 &&
230         git add file2 &&
231         git commit -m add.file2 file2 &&
232         git bundle create bundle3 -1 HEAD &&
233         (
234                 while read x && test -n "$x"
235                 do
236                         :;
237                 done
238                 cat
239         ) <bundle3 >bundle.pack &&
240         git index-pack bundle.pack &&
241         test_bundle_object_count bundle.pack 3
242 '
243
244 test_expect_success 'bundle should be able to create a full history' '
245
246         cd "$D" &&
247         git tag -a -m '1.0' v1.0 master &&
248         git bundle create bundle4 v1.0
249
250 '
251
252 ! rsync --help > /dev/null 2> /dev/null &&
253 say 'Skipping rsync tests because rsync was not found' || {
254 test_expect_success 'fetch via rsync' '
255         git pack-refs &&
256         mkdir rsynced &&
257         (cd rsynced &&
258          git init --bare &&
259          git fetch "rsync:$(pwd)/../.git" master:refs/heads/master &&
260          git gc --prune &&
261          test $(git rev-parse master) = $(cd .. && git rev-parse master) &&
262          git fsck --full)
263 '
264
265 test_expect_success 'push via rsync' '
266         mkdir rsynced2 &&
267         (cd rsynced2 &&
268          git init) &&
269         (cd rsynced &&
270          git push "rsync:$(pwd)/../rsynced2/.git" master) &&
271         (cd rsynced2 &&
272          git gc --prune &&
273          test $(git rev-parse master) = $(cd .. && git rev-parse master) &&
274          git fsck --full)
275 '
276
277 test_expect_success 'push via rsync' '
278         mkdir rsynced3 &&
279         (cd rsynced3 &&
280          git init) &&
281         git push --all "rsync:$(pwd)/rsynced3/.git" &&
282         (cd rsynced3 &&
283          test $(git rev-parse master) = $(cd .. && git rev-parse master) &&
284          git fsck --full)
285 '
286 }
287
288 test_expect_success 'fetch with a non-applying branch.<name>.merge' '
289         git config branch.master.remote yeti &&
290         git config branch.master.merge refs/heads/bigfoot &&
291         git config remote.blub.url one &&
292         git config remote.blub.fetch "refs/heads/*:refs/remotes/one/*" &&
293         git fetch blub
294 '
295
296 # URL supplied to fetch does not match the url of the configured branch's remote
297 test_expect_success 'fetch from GIT URL with a non-applying branch.<name>.merge [1]' '
298         one_head=$(cd one && git rev-parse HEAD) &&
299         this_head=$(git rev-parse HEAD) &&
300         git update-ref -d FETCH_HEAD &&
301         git fetch one &&
302         test $one_head = "$(git rev-parse --verify FETCH_HEAD)" &&
303         test $this_head = "$(git rev-parse --verify HEAD)"
304 '
305
306 # URL supplied to fetch matches the url of the configured branch's remote and
307 # the merge spec matches the branch the remote HEAD points to
308 test_expect_success 'fetch from GIT URL with a non-applying branch.<name>.merge [2]' '
309         one_ref=$(cd one && git symbolic-ref HEAD) &&
310         git config branch.master.remote blub &&
311         git config branch.master.merge "$one_ref" &&
312         git update-ref -d FETCH_HEAD &&
313         git fetch one &&
314         test $one_head = "$(git rev-parse --verify FETCH_HEAD)" &&
315         test $this_head = "$(git rev-parse --verify HEAD)"
316 '
317
318 # URL supplied to fetch matches the url of the configured branch's remote, but
319 # the merge spec does not match the branch the remote HEAD points to
320 test_expect_success 'fetch from GIT URL with a non-applying branch.<name>.merge [3]' '
321         git config branch.master.merge "${one_ref}_not" &&
322         git update-ref -d FETCH_HEAD &&
323         git fetch one &&
324         test $one_head = "$(git rev-parse --verify FETCH_HEAD)" &&
325         test $this_head = "$(git rev-parse --verify HEAD)"
326 '
327
328 # the strange name is: a\!'b
329 test_expect_success 'quoting of a strangely named repo' '
330         test_must_fail git fetch "a\\!'\''b" > result 2>&1 &&
331         cat result &&
332         grep "fatal: '\''a\\\\!'\''b'\''" result
333 '
334
335 test_expect_success 'bundle should record HEAD correctly' '
336
337         cd "$D" &&
338         git bundle create bundle5 HEAD master &&
339         git bundle list-heads bundle5 >actual &&
340         for h in HEAD refs/heads/master
341         do
342                 echo "$(git rev-parse --verify $h) $h"
343         done >expect &&
344         test_cmp expect actual
345
346 '
347
348 test_expect_success 'explicit fetch should not update tracking' '
349
350         cd "$D" &&
351         git branch -f side &&
352         (
353                 cd three &&
354                 o=$(git rev-parse --verify refs/remotes/origin/master) &&
355                 git fetch origin master &&
356                 n=$(git rev-parse --verify refs/remotes/origin/master) &&
357                 test "$o" = "$n" &&
358                 test_must_fail git rev-parse --verify refs/remotes/origin/side
359         )
360 '
361
362 test_expect_success 'explicit pull should not update tracking' '
363
364         cd "$D" &&
365         git branch -f side &&
366         (
367                 cd three &&
368                 o=$(git rev-parse --verify refs/remotes/origin/master) &&
369                 git pull origin master &&
370                 n=$(git rev-parse --verify refs/remotes/origin/master) &&
371                 test "$o" = "$n" &&
372                 test_must_fail git rev-parse --verify refs/remotes/origin/side
373         )
374 '
375
376 test_expect_success 'configured fetch updates tracking' '
377
378         cd "$D" &&
379         git branch -f side &&
380         (
381                 cd three &&
382                 o=$(git rev-parse --verify refs/remotes/origin/master) &&
383                 git fetch origin &&
384                 n=$(git rev-parse --verify refs/remotes/origin/master) &&
385                 test "$o" != "$n" &&
386                 git rev-parse --verify refs/remotes/origin/side
387         )
388 '
389
390 test_expect_success 'pushing nonexistent branch by mistake should not segv' '
391
392         cd "$D" &&
393         test_must_fail git push seven no:no
394
395 '
396
397 test_expect_success 'auto tag following fetches minimum' '
398
399         cd "$D" &&
400         git clone .git follow &&
401         git checkout HEAD^0 &&
402         (
403                 for i in 1 2 3 4 5 6 7
404                 do
405                         echo $i >>file &&
406                         git commit -m $i -a &&
407                         git tag -a -m $i excess-$i || exit 1
408                 done
409         ) &&
410         git checkout master &&
411         (
412                 cd follow &&
413                 git fetch
414         )
415 '
416
417 test_expect_success 'refuse to fetch into the current branch' '
418
419         test_must_fail git fetch . side:master
420
421 '
422
423 test_expect_success 'fetch into the current branch with --update-head-ok' '
424
425         git fetch --update-head-ok . side:master
426
427 '
428
429 test_expect_success 'fetch --dry-run' '
430
431         rm -f .git/FETCH_HEAD &&
432         git fetch --dry-run . &&
433         ! test -f .git/FETCH_HEAD
434 '
435
436 test_expect_success "should be able to fetch with duplicate refspecs" '
437         mkdir dups &&
438         cd dups &&
439         git init &&
440         git config branch.master.remote three &&
441         git config remote.three.url ../three/.git &&
442         git config remote.three.fetch +refs/heads/*:refs/remotes/origin/* &&
443         git config --add remote.three.fetch +refs/heads/*:refs/remotes/origin/* &&
444         git fetch three
445 '
446
447 test_done