git svn: make empty directory creation gc-aware
[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 'fetch with pushInsteadOf (should not rewrite)' '
126         mk_empty &&
127         (
128                 TRASH=$(pwd)/ &&
129                 cd testrepo &&
130                 git config "url.trash/.pushInsteadOf" "$TRASH" &&
131                 git config remote.up.url "$TRASH." &&
132                 git config remote.up.fetch "refs/heads/*:refs/remotes/origin/*" &&
133                 git fetch up &&
134
135                 r=$(git show-ref -s --verify refs/remotes/origin/master) &&
136                 test "z$r" = "z$the_commit" &&
137
138                 test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
139         )
140 '
141
142 test_expect_success 'push without wildcard' '
143         mk_empty &&
144
145         git push testrepo refs/heads/master:refs/remotes/origin/master &&
146         (
147                 cd testrepo &&
148                 r=$(git show-ref -s --verify refs/remotes/origin/master) &&
149                 test "z$r" = "z$the_commit" &&
150
151                 test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
152         )
153 '
154
155 test_expect_success 'push with wildcard' '
156         mk_empty &&
157
158         git push testrepo "refs/heads/*:refs/remotes/origin/*" &&
159         (
160                 cd testrepo &&
161                 r=$(git show-ref -s --verify refs/remotes/origin/master) &&
162                 test "z$r" = "z$the_commit" &&
163
164                 test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
165         )
166 '
167
168 test_expect_success 'push with insteadOf' '
169         mk_empty &&
170         TRASH="$(pwd)/" &&
171         git config "url.$TRASH.insteadOf" trash/ &&
172         git push trash/testrepo refs/heads/master:refs/remotes/origin/master &&
173         (
174                 cd testrepo &&
175                 r=$(git show-ref -s --verify refs/remotes/origin/master) &&
176                 test "z$r" = "z$the_commit" &&
177
178                 test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
179         )
180 '
181
182 test_expect_success 'push with pushInsteadOf' '
183         mk_empty &&
184         TRASH="$(pwd)/" &&
185         git config "url.$TRASH.pushInsteadOf" trash/ &&
186         git push trash/testrepo refs/heads/master:refs/remotes/origin/master &&
187         (
188                 cd testrepo &&
189                 r=$(git show-ref -s --verify refs/remotes/origin/master) &&
190                 test "z$r" = "z$the_commit" &&
191
192                 test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
193         )
194 '
195
196 test_expect_success 'push with pushInsteadOf and explicit pushurl (pushInsteadOf should not rewrite)' '
197         mk_empty &&
198         TRASH="$(pwd)/" &&
199         git config "url.trash2/.pushInsteadOf" trash/ &&
200         git config remote.r.url trash/wrong &&
201         git config remote.r.pushurl "$TRASH/testrepo" &&
202         git push r refs/heads/master:refs/remotes/origin/master &&
203         (
204                 cd testrepo &&
205                 r=$(git show-ref -s --verify refs/remotes/origin/master) &&
206                 test "z$r" = "z$the_commit" &&
207
208                 test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
209         )
210 '
211
212 test_expect_success 'push with matching heads' '
213
214         mk_test heads/master &&
215         git push testrepo &&
216         check_push_result $the_commit heads/master
217
218 '
219
220 test_expect_success 'push with matching heads on the command line' '
221
222         mk_test heads/master &&
223         git push testrepo : &&
224         check_push_result $the_commit heads/master
225
226 '
227
228 test_expect_success 'failed (non-fast-forward) push with matching heads' '
229
230         mk_test heads/master &&
231         git push testrepo : &&
232         git commit --amend -massaged &&
233         test_must_fail git push testrepo &&
234         check_push_result $the_commit heads/master &&
235         git reset --hard $the_commit
236
237 '
238
239 test_expect_success 'push --force with matching heads' '
240
241         mk_test heads/master &&
242         git push testrepo : &&
243         git commit --amend -massaged &&
244         git push --force testrepo &&
245         ! check_push_result $the_commit heads/master &&
246         git reset --hard $the_commit
247
248 '
249
250 test_expect_success 'push with matching heads and forced update' '
251
252         mk_test heads/master &&
253         git push testrepo : &&
254         git commit --amend -massaged &&
255         git push testrepo +: &&
256         ! check_push_result $the_commit heads/master &&
257         git reset --hard $the_commit
258
259 '
260
261 test_expect_success 'push with no ambiguity (1)' '
262
263         mk_test heads/master &&
264         git push testrepo master:master &&
265         check_push_result $the_commit heads/master
266
267 '
268
269 test_expect_success 'push with no ambiguity (2)' '
270
271         mk_test remotes/origin/master &&
272         git push testrepo master:origin/master &&
273         check_push_result $the_commit remotes/origin/master
274
275 '
276
277 test_expect_success 'push with colon-less refspec, no ambiguity' '
278
279         mk_test heads/master heads/t/master &&
280         git branch -f t/master master &&
281         git push testrepo master &&
282         check_push_result $the_commit heads/master &&
283         check_push_result $the_first_commit heads/t/master
284
285 '
286
287 test_expect_success 'push with weak ambiguity (1)' '
288
289         mk_test heads/master remotes/origin/master &&
290         git push testrepo master:master &&
291         check_push_result $the_commit heads/master &&
292         check_push_result $the_first_commit remotes/origin/master
293
294 '
295
296 test_expect_success 'push with weak ambiguity (2)' '
297
298         mk_test heads/master remotes/origin/master remotes/another/master &&
299         git push testrepo master:master &&
300         check_push_result $the_commit heads/master &&
301         check_push_result $the_first_commit remotes/origin/master remotes/another/master
302
303 '
304
305 test_expect_success 'push with ambiguity' '
306
307         mk_test heads/frotz tags/frotz &&
308         if git push testrepo master:frotz
309         then
310                 echo "Oops, should have failed"
311                 false
312         else
313                 check_push_result $the_first_commit heads/frotz tags/frotz
314         fi
315
316 '
317
318 test_expect_success 'push with colon-less refspec (1)' '
319
320         mk_test heads/frotz tags/frotz &&
321         git branch -f frotz master &&
322         git push testrepo frotz &&
323         check_push_result $the_commit heads/frotz &&
324         check_push_result $the_first_commit tags/frotz
325
326 '
327
328 test_expect_success 'push with colon-less refspec (2)' '
329
330         mk_test heads/frotz tags/frotz &&
331         if git show-ref --verify -q refs/heads/frotz
332         then
333                 git branch -D frotz
334         fi &&
335         git tag -f frotz &&
336         git push testrepo frotz &&
337         check_push_result $the_commit tags/frotz &&
338         check_push_result $the_first_commit heads/frotz
339
340 '
341
342 test_expect_success 'push with colon-less refspec (3)' '
343
344         mk_test &&
345         if git show-ref --verify -q refs/tags/frotz
346         then
347                 git tag -d frotz
348         fi &&
349         git branch -f frotz master &&
350         git push testrepo frotz &&
351         check_push_result $the_commit heads/frotz &&
352         test 1 = $( cd testrepo && git show-ref | wc -l )
353 '
354
355 test_expect_success 'push with colon-less refspec (4)' '
356
357         mk_test &&
358         if git show-ref --verify -q refs/heads/frotz
359         then
360                 git branch -D frotz
361         fi &&
362         git tag -f frotz &&
363         git push testrepo frotz &&
364         check_push_result $the_commit tags/frotz &&
365         test 1 = $( cd testrepo && git show-ref | wc -l )
366
367 '
368
369 test_expect_success 'push head with non-existant, incomplete dest' '
370
371         mk_test &&
372         git push testrepo master:branch &&
373         check_push_result $the_commit heads/branch
374
375 '
376
377 test_expect_success 'push tag with non-existant, incomplete dest' '
378
379         mk_test &&
380         git tag -f v1.0 &&
381         git push testrepo v1.0:tag &&
382         check_push_result $the_commit tags/tag
383
384 '
385
386 test_expect_success 'push sha1 with non-existant, incomplete dest' '
387
388         mk_test &&
389         test_must_fail git push testrepo `git rev-parse master`:foo
390
391 '
392
393 test_expect_success 'push ref expression with non-existant, incomplete dest' '
394
395         mk_test &&
396         test_must_fail git push testrepo master^:branch
397
398 '
399
400 test_expect_success 'push with HEAD' '
401
402         mk_test heads/master &&
403         git checkout master &&
404         git push testrepo HEAD &&
405         check_push_result $the_commit heads/master
406
407 '
408
409 test_expect_success 'push with HEAD nonexisting at remote' '
410
411         mk_test heads/master &&
412         git checkout -b local master &&
413         git push testrepo HEAD &&
414         check_push_result $the_commit heads/local
415 '
416
417 test_expect_success 'push with +HEAD' '
418
419         mk_test heads/master &&
420         git checkout master &&
421         git branch -D local &&
422         git checkout -b local &&
423         git push testrepo master local &&
424         check_push_result $the_commit heads/master &&
425         check_push_result $the_commit heads/local &&
426
427         # Without force rewinding should fail
428         git reset --hard HEAD^ &&
429         test_must_fail git push testrepo HEAD &&
430         check_push_result $the_commit heads/local &&
431
432         # With force rewinding should succeed
433         git push testrepo +HEAD &&
434         check_push_result $the_first_commit heads/local
435
436 '
437
438 test_expect_success 'push HEAD with non-existant, incomplete dest' '
439
440         mk_test &&
441         git checkout master &&
442         git push testrepo HEAD:branch &&
443         check_push_result $the_commit heads/branch
444
445 '
446
447 test_expect_success 'push with config remote.*.push = HEAD' '
448
449         mk_test heads/local &&
450         git checkout master &&
451         git branch -f local $the_commit &&
452         (
453                 cd testrepo &&
454                 git checkout local &&
455                 git reset --hard $the_first_commit
456         ) &&
457         git config remote.there.url testrepo &&
458         git config remote.there.push HEAD &&
459         git config branch.master.remote there &&
460         git push &&
461         check_push_result $the_commit heads/master &&
462         check_push_result $the_first_commit heads/local
463 '
464
465 # clean up the cruft left with the previous one
466 git config --remove-section remote.there
467 git config --remove-section branch.master
468
469 test_expect_success 'push with config remote.*.pushurl' '
470
471         mk_test heads/master &&
472         git checkout master &&
473         git config remote.there.url test2repo &&
474         git config remote.there.pushurl testrepo &&
475         git push there &&
476         check_push_result $the_commit heads/master
477 '
478
479 # clean up the cruft left with the previous one
480 git config --remove-section remote.there
481
482 test_expect_success 'push with dry-run' '
483
484         mk_test heads/master &&
485         (cd testrepo &&
486          old_commit=$(git show-ref -s --verify refs/heads/master)) &&
487         git push --dry-run testrepo &&
488         check_push_result $old_commit heads/master
489 '
490
491 test_expect_success 'push updates local refs' '
492
493         mk_test heads/master &&
494         mk_child child &&
495         (cd child &&
496                 git pull .. master &&
497                 git push &&
498         test $(git rev-parse master) = $(git rev-parse remotes/origin/master))
499
500 '
501
502 test_expect_success 'push updates up-to-date local refs' '
503
504         mk_test heads/master &&
505         mk_child child1 &&
506         mk_child child2 &&
507         (cd child1 && git pull .. master && git push) &&
508         (cd child2 &&
509                 git pull ../child1 master &&
510                 git push &&
511         test $(git rev-parse master) = $(git rev-parse remotes/origin/master))
512
513 '
514
515 test_expect_success 'push preserves up-to-date packed refs' '
516
517         mk_test heads/master &&
518         mk_child child &&
519         (cd child &&
520                 git push &&
521         ! test -f .git/refs/remotes/origin/master)
522
523 '
524
525 test_expect_success 'push does not update local refs on failure' '
526
527         mk_test heads/master &&
528         mk_child child &&
529         mkdir testrepo/.git/hooks &&
530         echo exit 1 >testrepo/.git/hooks/pre-receive &&
531         chmod +x testrepo/.git/hooks/pre-receive &&
532         (cd child &&
533                 git pull .. master
534                 test_must_fail git push &&
535                 test $(git rev-parse master) != \
536                         $(git rev-parse remotes/origin/master))
537
538 '
539
540 test_expect_success 'allow deleting an invalid remote ref' '
541
542         mk_test heads/master &&
543         rm -f testrepo/.git/objects/??/* &&
544         git push testrepo :refs/heads/master &&
545         (cd testrepo && test_must_fail git rev-parse --verify refs/heads/master)
546
547 '
548
549 test_expect_success 'warn on push to HEAD of non-bare repository' '
550         mk_test heads/master
551         (cd testrepo &&
552                 git checkout master &&
553                 git config receive.denyCurrentBranch warn) &&
554         git push testrepo master 2>stderr &&
555         grep "warning: updating the current branch" stderr
556 '
557
558 test_expect_success 'deny push to HEAD of non-bare repository' '
559         mk_test heads/master
560         (cd testrepo &&
561                 git checkout master &&
562                 git config receive.denyCurrentBranch true) &&
563         test_must_fail git push testrepo master
564 '
565
566 test_expect_success 'allow push to HEAD of bare repository (bare)' '
567         mk_test heads/master
568         (cd testrepo &&
569                 git checkout master &&
570                 git config receive.denyCurrentBranch true &&
571                 git config core.bare true) &&
572         git push testrepo master 2>stderr &&
573         ! grep "warning: updating the current branch" stderr
574 '
575
576 test_expect_success 'allow push to HEAD of non-bare repository (config)' '
577         mk_test heads/master
578         (cd testrepo &&
579                 git checkout master &&
580                 git config receive.denyCurrentBranch false
581         ) &&
582         git push testrepo master 2>stderr &&
583         ! grep "warning: updating the current branch" stderr
584 '
585
586 test_expect_success 'fetch with branches' '
587         mk_empty &&
588         git branch second $the_first_commit &&
589         git checkout second &&
590         echo ".." > testrepo/.git/branches/branch1 &&
591         (cd testrepo &&
592                 git fetch branch1 &&
593                 r=$(git show-ref -s --verify refs/heads/branch1) &&
594                 test "z$r" = "z$the_commit" &&
595                 test 1 = $(git for-each-ref refs/heads | wc -l)
596         ) &&
597         git checkout master
598 '
599
600 test_expect_success 'fetch with branches containing #' '
601         mk_empty &&
602         echo "..#second" > testrepo/.git/branches/branch2 &&
603         (cd testrepo &&
604                 git fetch branch2 &&
605                 r=$(git show-ref -s --verify refs/heads/branch2) &&
606                 test "z$r" = "z$the_first_commit" &&
607                 test 1 = $(git for-each-ref refs/heads | wc -l)
608         ) &&
609         git checkout master
610 '
611
612 test_expect_success 'push with branches' '
613         mk_empty &&
614         git checkout second &&
615         echo "testrepo" > .git/branches/branch1 &&
616         git push branch1 &&
617         (cd testrepo &&
618                 r=$(git show-ref -s --verify refs/heads/master) &&
619                 test "z$r" = "z$the_first_commit" &&
620                 test 1 = $(git for-each-ref refs/heads | wc -l)
621         )
622 '
623
624 test_expect_success 'push with branches containing #' '
625         mk_empty &&
626         echo "testrepo#branch3" > .git/branches/branch2 &&
627         git push branch2 &&
628         (cd testrepo &&
629                 r=$(git show-ref -s --verify refs/heads/branch3) &&
630                 test "z$r" = "z$the_first_commit" &&
631                 test 1 = $(git for-each-ref refs/heads | wc -l)
632         ) &&
633         git checkout master
634 '
635
636 test_done