Merge git://git.bogomips.org/git-svn
[git] / t / t5516-fetch-push.sh
1 #!/bin/sh
2
3 test_description='fetching and pushing, with or without wildcard'
4
5 . ./test-lib.sh
6
7 D=`pwd`
8
9 mk_empty () {
10         rm -fr testrepo &&
11         mkdir testrepo &&
12         (
13                 cd testrepo &&
14                 git init &&
15                 mv .git/hooks .git/hooks-disabled
16         )
17 }
18
19 mk_test () {
20         mk_empty &&
21         (
22                 for ref in "$@"
23                 do
24                         git push testrepo $the_first_commit:refs/$ref || {
25                                 echo "Oops, push refs/$ref failure"
26                                 exit 1
27                         }
28                 done &&
29                 cd testrepo &&
30                 for ref in "$@"
31                 do
32                         r=$(git show-ref -s --verify refs/$ref) &&
33                         test "z$r" = "z$the_first_commit" || {
34                                 echo "Oops, refs/$ref is wrong"
35                                 exit 1
36                         }
37                 done &&
38                 git fsck --full
39         )
40 }
41
42 mk_child() {
43         rm -rf "$1" &&
44         git clone testrepo "$1"
45 }
46
47 check_push_result () {
48         (
49                 cd testrepo &&
50                 it="$1" &&
51                 shift
52                 for ref in "$@"
53                 do
54                         r=$(git show-ref -s --verify refs/$ref) &&
55                         test "z$r" = "z$it" || {
56                                 echo "Oops, refs/$ref is wrong"
57                                 exit 1
58                         }
59                 done &&
60                 git fsck --full
61         )
62 }
63
64 test_expect_success setup '
65
66         : >path1 &&
67         git add path1 &&
68         test_tick &&
69         git commit -a -m repo &&
70         the_first_commit=$(git show-ref -s --verify refs/heads/master) &&
71
72         : >path2 &&
73         git add path2 &&
74         test_tick &&
75         git commit -a -m second &&
76         the_commit=$(git show-ref -s --verify refs/heads/master)
77
78 '
79
80 test_expect_success 'fetch without wildcard' '
81         mk_empty &&
82         (
83                 cd testrepo &&
84                 git fetch .. refs/heads/master:refs/remotes/origin/master &&
85
86                 r=$(git show-ref -s --verify refs/remotes/origin/master) &&
87                 test "z$r" = "z$the_commit" &&
88
89                 test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
90         )
91 '
92
93 test_expect_success 'fetch with wildcard' '
94         mk_empty &&
95         (
96                 cd testrepo &&
97                 git config remote.up.url .. &&
98                 git config remote.up.fetch "refs/heads/*:refs/remotes/origin/*" &&
99                 git fetch up &&
100
101                 r=$(git show-ref -s --verify refs/remotes/origin/master) &&
102                 test "z$r" = "z$the_commit" &&
103
104                 test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
105         )
106 '
107
108 test_expect_success 'fetch with insteadOf' '
109         mk_empty &&
110         (
111                 TRASH=$(pwd)/ &&
112                 cd testrepo &&
113                 git config "url.$TRASH.insteadOf" trash/ &&
114                 git config remote.up.url trash/. &&
115                 git config remote.up.fetch "refs/heads/*:refs/remotes/origin/*" &&
116                 git fetch up &&
117
118                 r=$(git show-ref -s --verify refs/remotes/origin/master) &&
119                 test "z$r" = "z$the_commit" &&
120
121                 test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
122         )
123 '
124
125 test_expect_success 'push without wildcard' '
126         mk_empty &&
127
128         git push testrepo refs/heads/master:refs/remotes/origin/master &&
129         (
130                 cd testrepo &&
131                 r=$(git show-ref -s --verify refs/remotes/origin/master) &&
132                 test "z$r" = "z$the_commit" &&
133
134                 test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
135         )
136 '
137
138 test_expect_success 'push with wildcard' '
139         mk_empty &&
140
141         git push testrepo "refs/heads/*:refs/remotes/origin/*" &&
142         (
143                 cd testrepo &&
144                 r=$(git show-ref -s --verify refs/remotes/origin/master) &&
145                 test "z$r" = "z$the_commit" &&
146
147                 test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
148         )
149 '
150
151 test_expect_success 'push with insteadOf' '
152         mk_empty &&
153         TRASH="$(pwd)/" &&
154         git config "url.$TRASH.insteadOf" trash/ &&
155         git push trash/testrepo refs/heads/master:refs/remotes/origin/master &&
156         (
157                 cd testrepo &&
158                 r=$(git show-ref -s --verify refs/remotes/origin/master) &&
159                 test "z$r" = "z$the_commit" &&
160
161                 test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
162         )
163 '
164
165 test_expect_success 'push with matching heads' '
166
167         mk_test heads/master &&
168         git push testrepo &&
169         check_push_result $the_commit heads/master
170
171 '
172
173 test_expect_success 'push with matching heads on the command line' '
174
175         mk_test heads/master &&
176         git push testrepo : &&
177         check_push_result $the_commit heads/master
178
179 '
180
181 test_expect_success 'failed (non-fast-forward) push with matching heads' '
182
183         mk_test heads/master &&
184         git push testrepo : &&
185         git commit --amend -massaged &&
186         test_must_fail git push testrepo &&
187         check_push_result $the_commit heads/master &&
188         git reset --hard $the_commit
189
190 '
191
192 test_expect_success 'push --force with matching heads' '
193
194         mk_test heads/master &&
195         git push testrepo : &&
196         git commit --amend -massaged &&
197         git push --force testrepo &&
198         ! check_push_result $the_commit heads/master &&
199         git reset --hard $the_commit
200
201 '
202
203 test_expect_success 'push with matching heads and forced update' '
204
205         mk_test heads/master &&
206         git push testrepo : &&
207         git commit --amend -massaged &&
208         git push testrepo +: &&
209         ! check_push_result $the_commit heads/master &&
210         git reset --hard $the_commit
211
212 '
213
214 test_expect_success 'push with no ambiguity (1)' '
215
216         mk_test heads/master &&
217         git push testrepo master:master &&
218         check_push_result $the_commit heads/master
219
220 '
221
222 test_expect_success 'push with no ambiguity (2)' '
223
224         mk_test remotes/origin/master &&
225         git push testrepo master:origin/master &&
226         check_push_result $the_commit remotes/origin/master
227
228 '
229
230 test_expect_success 'push with colon-less refspec, no ambiguity' '
231
232         mk_test heads/master heads/t/master &&
233         git branch -f t/master master &&
234         git push testrepo master &&
235         check_push_result $the_commit heads/master &&
236         check_push_result $the_first_commit heads/t/master
237
238 '
239
240 test_expect_success 'push with weak ambiguity (1)' '
241
242         mk_test heads/master remotes/origin/master &&
243         git push testrepo master:master &&
244         check_push_result $the_commit heads/master &&
245         check_push_result $the_first_commit remotes/origin/master
246
247 '
248
249 test_expect_success 'push with weak ambiguity (2)' '
250
251         mk_test heads/master remotes/origin/master remotes/another/master &&
252         git push testrepo master:master &&
253         check_push_result $the_commit heads/master &&
254         check_push_result $the_first_commit remotes/origin/master remotes/another/master
255
256 '
257
258 test_expect_success 'push with ambiguity' '
259
260         mk_test heads/frotz tags/frotz &&
261         if git push testrepo master:frotz
262         then
263                 echo "Oops, should have failed"
264                 false
265         else
266                 check_push_result $the_first_commit heads/frotz tags/frotz
267         fi
268
269 '
270
271 test_expect_success 'push with colon-less refspec (1)' '
272
273         mk_test heads/frotz tags/frotz &&
274         git branch -f frotz master &&
275         git push testrepo frotz &&
276         check_push_result $the_commit heads/frotz &&
277         check_push_result $the_first_commit tags/frotz
278
279 '
280
281 test_expect_success 'push with colon-less refspec (2)' '
282
283         mk_test heads/frotz tags/frotz &&
284         if git show-ref --verify -q refs/heads/frotz
285         then
286                 git branch -D frotz
287         fi &&
288         git tag -f frotz &&
289         git push testrepo frotz &&
290         check_push_result $the_commit tags/frotz &&
291         check_push_result $the_first_commit heads/frotz
292
293 '
294
295 test_expect_success 'push with colon-less refspec (3)' '
296
297         mk_test &&
298         if git show-ref --verify -q refs/tags/frotz
299         then
300                 git tag -d frotz
301         fi &&
302         git branch -f frotz master &&
303         git push testrepo frotz &&
304         check_push_result $the_commit heads/frotz &&
305         test 1 = $( cd testrepo && git show-ref | wc -l )
306 '
307
308 test_expect_success 'push with colon-less refspec (4)' '
309
310         mk_test &&
311         if git show-ref --verify -q refs/heads/frotz
312         then
313                 git branch -D frotz
314         fi &&
315         git tag -f frotz &&
316         git push testrepo frotz &&
317         check_push_result $the_commit tags/frotz &&
318         test 1 = $( cd testrepo && git show-ref | wc -l )
319
320 '
321
322 test_expect_success 'push head with non-existant, incomplete dest' '
323
324         mk_test &&
325         git push testrepo master:branch &&
326         check_push_result $the_commit heads/branch
327
328 '
329
330 test_expect_success 'push tag with non-existant, incomplete dest' '
331
332         mk_test &&
333         git tag -f v1.0 &&
334         git push testrepo v1.0:tag &&
335         check_push_result $the_commit tags/tag
336
337 '
338
339 test_expect_success 'push sha1 with non-existant, incomplete dest' '
340
341         mk_test &&
342         test_must_fail git push testrepo `git rev-parse master`:foo
343
344 '
345
346 test_expect_success 'push ref expression with non-existant, incomplete dest' '
347
348         mk_test &&
349         test_must_fail git push testrepo master^:branch
350
351 '
352
353 test_expect_success 'push with HEAD' '
354
355         mk_test heads/master &&
356         git checkout master &&
357         git push testrepo HEAD &&
358         check_push_result $the_commit heads/master
359
360 '
361
362 test_expect_success 'push with HEAD nonexisting at remote' '
363
364         mk_test heads/master &&
365         git checkout -b local master &&
366         git push testrepo HEAD &&
367         check_push_result $the_commit heads/local
368 '
369
370 test_expect_success 'push with +HEAD' '
371
372         mk_test heads/master &&
373         git checkout master &&
374         git branch -D local &&
375         git checkout -b local &&
376         git push testrepo master local &&
377         check_push_result $the_commit heads/master &&
378         check_push_result $the_commit heads/local &&
379
380         # Without force rewinding should fail
381         git reset --hard HEAD^ &&
382         test_must_fail git push testrepo HEAD &&
383         check_push_result $the_commit heads/local &&
384
385         # With force rewinding should succeed
386         git push testrepo +HEAD &&
387         check_push_result $the_first_commit heads/local
388
389 '
390
391 test_expect_success 'push HEAD with non-existant, incomplete dest' '
392
393         mk_test &&
394         git checkout master &&
395         git push testrepo HEAD:branch &&
396         check_push_result $the_commit heads/branch
397
398 '
399
400 test_expect_success 'push with config remote.*.push = HEAD' '
401
402         mk_test heads/local &&
403         git checkout master &&
404         git branch -f local $the_commit &&
405         (
406                 cd testrepo &&
407                 git checkout local &&
408                 git reset --hard $the_first_commit
409         ) &&
410         git config remote.there.url testrepo &&
411         git config remote.there.push HEAD &&
412         git config branch.master.remote there &&
413         git push &&
414         check_push_result $the_commit heads/master &&
415         check_push_result $the_first_commit heads/local
416 '
417
418 # clean up the cruft left with the previous one
419 git config --remove-section remote.there
420 git config --remove-section branch.master
421
422 test_expect_success 'push with dry-run' '
423
424         mk_test heads/master &&
425         (cd testrepo &&
426          old_commit=$(git show-ref -s --verify refs/heads/master)) &&
427         git push --dry-run testrepo &&
428         check_push_result $old_commit heads/master
429 '
430
431 test_expect_success 'push updates local refs' '
432
433         mk_test heads/master &&
434         mk_child child &&
435         (cd child &&
436                 git pull .. master &&
437                 git push &&
438         test $(git rev-parse master) = $(git rev-parse remotes/origin/master))
439
440 '
441
442 test_expect_success 'push updates up-to-date local refs' '
443
444         mk_test heads/master &&
445         mk_child child1 &&
446         mk_child child2 &&
447         (cd child1 && git pull .. master && git push) &&
448         (cd child2 &&
449                 git pull ../child1 master &&
450                 git push &&
451         test $(git rev-parse master) = $(git rev-parse remotes/origin/master))
452
453 '
454
455 test_expect_success 'push preserves up-to-date packed refs' '
456
457         mk_test heads/master &&
458         mk_child child &&
459         (cd child &&
460                 git push &&
461         ! test -f .git/refs/remotes/origin/master)
462
463 '
464
465 test_expect_success 'push does not update local refs on failure' '
466
467         mk_test heads/master &&
468         mk_child child &&
469         mkdir testrepo/.git/hooks &&
470         echo exit 1 >testrepo/.git/hooks/pre-receive &&
471         chmod +x testrepo/.git/hooks/pre-receive &&
472         (cd child &&
473                 git pull .. master
474                 test_must_fail git push &&
475                 test $(git rev-parse master) != \
476                         $(git rev-parse remotes/origin/master))
477
478 '
479
480 test_expect_success 'allow deleting an invalid remote ref' '
481
482         mk_test heads/master &&
483         rm -f testrepo/.git/objects/??/* &&
484         git push testrepo :refs/heads/master &&
485         (cd testrepo && test_must_fail git rev-parse --verify refs/heads/master)
486
487 '
488
489 test_expect_success 'warn on push to HEAD of non-bare repository' '
490         mk_test heads/master
491         (cd testrepo &&
492                 git checkout master &&
493                 git config receive.denyCurrentBranch warn) &&
494         git push testrepo master 2>stderr &&
495         grep "warning.*this may cause confusion" stderr
496 '
497
498 test_expect_success 'deny push to HEAD of non-bare repository' '
499         mk_test heads/master
500         (cd testrepo &&
501                 git checkout master &&
502                 git config receive.denyCurrentBranch true) &&
503         test_must_fail git push testrepo master
504 '
505
506 test_expect_success 'allow push to HEAD of bare repository (bare)' '
507         mk_test heads/master
508         (cd testrepo &&
509                 git checkout master &&
510                 git config receive.denyCurrentBranch true &&
511                 git config core.bare true) &&
512         git push testrepo master 2>stderr &&
513         ! grep "warning.*this may cause confusion" stderr
514 '
515
516 test_expect_success 'allow push to HEAD of non-bare repository (config)' '
517         mk_test heads/master
518         (cd testrepo &&
519                 git checkout master &&
520                 git config receive.denyCurrentBranch false
521         ) &&
522         git push testrepo master 2>stderr &&
523         ! grep "warning.*this may cause confusion" stderr
524 '
525
526 test_expect_success 'fetch with branches' '
527         mk_empty &&
528         git branch second $the_first_commit &&
529         git checkout second &&
530         echo ".." > testrepo/.git/branches/branch1 &&
531         (cd testrepo &&
532                 git fetch branch1 &&
533                 r=$(git show-ref -s --verify refs/heads/branch1) &&
534                 test "z$r" = "z$the_commit" &&
535                 test 1 = $(git for-each-ref refs/heads | wc -l)
536         ) &&
537         git checkout master
538 '
539
540 test_expect_success 'fetch with branches containing #' '
541         mk_empty &&
542         echo "..#second" > testrepo/.git/branches/branch2 &&
543         (cd testrepo &&
544                 git fetch branch2 &&
545                 r=$(git show-ref -s --verify refs/heads/branch2) &&
546                 test "z$r" = "z$the_first_commit" &&
547                 test 1 = $(git for-each-ref refs/heads | wc -l)
548         ) &&
549         git checkout master
550 '
551
552 test_expect_success 'push with branches' '
553         mk_empty &&
554         git checkout second &&
555         echo "testrepo" > .git/branches/branch1 &&
556         git push branch1 &&
557         (cd testrepo &&
558                 r=$(git show-ref -s --verify refs/heads/master) &&
559                 test "z$r" = "z$the_first_commit" &&
560                 test 1 = $(git for-each-ref refs/heads | wc -l)
561         )
562 '
563
564 test_expect_success 'push with branches containing #' '
565         mk_empty &&
566         echo "testrepo#branch3" > .git/branches/branch2 &&
567         git push branch2 &&
568         (cd testrepo &&
569                 r=$(git show-ref -s --verify refs/heads/branch3) &&
570                 test "z$r" = "z$the_first_commit" &&
571                 test 1 = $(git for-each-ref refs/heads | wc -l)
572         ) &&
573         git checkout master
574 '
575
576 test_done