git-p4 tests: refactor and cleanup
[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                 git config receive.denyCurrentBranch warn &&
16                 mv .git/hooks .git/hooks-disabled
17         )
18 }
19
20 mk_test () {
21         mk_empty &&
22         (
23                 for ref in "$@"
24                 do
25                         git push testrepo $the_first_commit:refs/$ref || {
26                                 echo "Oops, push refs/$ref failure"
27                                 exit 1
28                         }
29                 done &&
30                 cd testrepo &&
31                 for ref in "$@"
32                 do
33                         r=$(git show-ref -s --verify refs/$ref) &&
34                         test "z$r" = "z$the_first_commit" || {
35                                 echo "Oops, refs/$ref is wrong"
36                                 exit 1
37                         }
38                 done &&
39                 git fsck --full
40         )
41 }
42
43 mk_child() {
44         rm -rf "$1" &&
45         git clone testrepo "$1"
46 }
47
48 check_push_result () {
49         (
50                 cd testrepo &&
51                 it="$1" &&
52                 shift
53                 for ref in "$@"
54                 do
55                         r=$(git show-ref -s --verify refs/$ref) &&
56                         test "z$r" = "z$it" || {
57                                 echo "Oops, refs/$ref is wrong"
58                                 exit 1
59                         }
60                 done &&
61                 git fsck --full
62         )
63 }
64
65 test_expect_success setup '
66
67         >path1 &&
68         git add path1 &&
69         test_tick &&
70         git commit -a -m repo &&
71         the_first_commit=$(git show-ref -s --verify refs/heads/master) &&
72
73         >path2 &&
74         git add path2 &&
75         test_tick &&
76         git commit -a -m second &&
77         the_commit=$(git show-ref -s --verify refs/heads/master)
78
79 '
80
81 test_expect_success 'fetch without wildcard' '
82         mk_empty &&
83         (
84                 cd testrepo &&
85                 git fetch .. refs/heads/master:refs/remotes/origin/master &&
86
87                 r=$(git show-ref -s --verify refs/remotes/origin/master) &&
88                 test "z$r" = "z$the_commit" &&
89
90                 test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
91         )
92 '
93
94 test_expect_success 'fetch with wildcard' '
95         mk_empty &&
96         (
97                 cd testrepo &&
98                 git config remote.up.url .. &&
99                 git config remote.up.fetch "refs/heads/*:refs/remotes/origin/*" &&
100                 git fetch up &&
101
102                 r=$(git show-ref -s --verify refs/remotes/origin/master) &&
103                 test "z$r" = "z$the_commit" &&
104
105                 test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
106         )
107 '
108
109 test_expect_success 'fetch with insteadOf' '
110         mk_empty &&
111         (
112                 TRASH=$(pwd)/ &&
113                 cd testrepo &&
114                 git config "url.$TRASH.insteadOf" trash/ &&
115                 git config remote.up.url trash/. &&
116                 git config remote.up.fetch "refs/heads/*:refs/remotes/origin/*" &&
117                 git fetch up &&
118
119                 r=$(git show-ref -s --verify refs/remotes/origin/master) &&
120                 test "z$r" = "z$the_commit" &&
121
122                 test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
123         )
124 '
125
126 test_expect_success 'fetch with pushInsteadOf (should not rewrite)' '
127         mk_empty &&
128         (
129                 TRASH=$(pwd)/ &&
130                 cd testrepo &&
131                 git config "url.trash/.pushInsteadOf" "$TRASH" &&
132                 git config remote.up.url "$TRASH." &&
133                 git config remote.up.fetch "refs/heads/*:refs/remotes/origin/*" &&
134                 git fetch up &&
135
136                 r=$(git show-ref -s --verify refs/remotes/origin/master) &&
137                 test "z$r" = "z$the_commit" &&
138
139                 test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
140         )
141 '
142
143 test_expect_success 'push without wildcard' '
144         mk_empty &&
145
146         git push testrepo refs/heads/master:refs/remotes/origin/master &&
147         (
148                 cd testrepo &&
149                 r=$(git show-ref -s --verify refs/remotes/origin/master) &&
150                 test "z$r" = "z$the_commit" &&
151
152                 test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
153         )
154 '
155
156 test_expect_success 'push with wildcard' '
157         mk_empty &&
158
159         git push testrepo "refs/heads/*:refs/remotes/origin/*" &&
160         (
161                 cd testrepo &&
162                 r=$(git show-ref -s --verify refs/remotes/origin/master) &&
163                 test "z$r" = "z$the_commit" &&
164
165                 test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
166         )
167 '
168
169 test_expect_success 'push with insteadOf' '
170         mk_empty &&
171         TRASH="$(pwd)/" &&
172         git config "url.$TRASH.insteadOf" trash/ &&
173         git push trash/testrepo refs/heads/master:refs/remotes/origin/master &&
174         (
175                 cd testrepo &&
176                 r=$(git show-ref -s --verify refs/remotes/origin/master) &&
177                 test "z$r" = "z$the_commit" &&
178
179                 test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
180         )
181 '
182
183 test_expect_success 'push with pushInsteadOf' '
184         mk_empty &&
185         TRASH="$(pwd)/" &&
186         git config "url.$TRASH.pushInsteadOf" trash/ &&
187         git push trash/testrepo refs/heads/master:refs/remotes/origin/master &&
188         (
189                 cd testrepo &&
190                 r=$(git show-ref -s --verify refs/remotes/origin/master) &&
191                 test "z$r" = "z$the_commit" &&
192
193                 test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
194         )
195 '
196
197 test_expect_success 'push with pushInsteadOf and explicit pushurl (pushInsteadOf should not rewrite)' '
198         mk_empty &&
199         TRASH="$(pwd)/" &&
200         git config "url.trash2/.pushInsteadOf" trash/ &&
201         git config remote.r.url trash/wrong &&
202         git config remote.r.pushurl "$TRASH/testrepo" &&
203         git push r refs/heads/master:refs/remotes/origin/master &&
204         (
205                 cd testrepo &&
206                 r=$(git show-ref -s --verify refs/remotes/origin/master) &&
207                 test "z$r" = "z$the_commit" &&
208
209                 test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
210         )
211 '
212
213 test_expect_success 'push with matching heads' '
214
215         mk_test heads/master &&
216         git push testrepo &&
217         check_push_result $the_commit heads/master
218
219 '
220
221 test_expect_success 'push with matching heads on the command line' '
222
223         mk_test heads/master &&
224         git push testrepo : &&
225         check_push_result $the_commit heads/master
226
227 '
228
229 test_expect_success 'failed (non-fast-forward) push with matching heads' '
230
231         mk_test heads/master &&
232         git push testrepo : &&
233         git commit --amend -massaged &&
234         test_must_fail git push testrepo &&
235         check_push_result $the_commit heads/master &&
236         git reset --hard $the_commit
237
238 '
239
240 test_expect_success 'push --force with matching heads' '
241
242         mk_test heads/master &&
243         git push testrepo : &&
244         git commit --amend -massaged &&
245         git push --force testrepo &&
246         ! check_push_result $the_commit heads/master &&
247         git reset --hard $the_commit
248
249 '
250
251 test_expect_success 'push with matching heads and forced update' '
252
253         mk_test heads/master &&
254         git push testrepo : &&
255         git commit --amend -massaged &&
256         git push testrepo +: &&
257         ! check_push_result $the_commit heads/master &&
258         git reset --hard $the_commit
259
260 '
261
262 test_expect_success 'push with no ambiguity (1)' '
263
264         mk_test heads/master &&
265         git push testrepo master:master &&
266         check_push_result $the_commit heads/master
267
268 '
269
270 test_expect_success 'push with no ambiguity (2)' '
271
272         mk_test remotes/origin/master &&
273         git push testrepo master:origin/master &&
274         check_push_result $the_commit remotes/origin/master
275
276 '
277
278 test_expect_success 'push with colon-less refspec, no ambiguity' '
279
280         mk_test heads/master heads/t/master &&
281         git branch -f t/master master &&
282         git push testrepo master &&
283         check_push_result $the_commit heads/master &&
284         check_push_result $the_first_commit heads/t/master
285
286 '
287
288 test_expect_success 'push with weak ambiguity (1)' '
289
290         mk_test heads/master remotes/origin/master &&
291         git push testrepo master:master &&
292         check_push_result $the_commit heads/master &&
293         check_push_result $the_first_commit remotes/origin/master
294
295 '
296
297 test_expect_success 'push with weak ambiguity (2)' '
298
299         mk_test heads/master remotes/origin/master remotes/another/master &&
300         git push testrepo master:master &&
301         check_push_result $the_commit heads/master &&
302         check_push_result $the_first_commit remotes/origin/master remotes/another/master
303
304 '
305
306 test_expect_success 'push with ambiguity' '
307
308         mk_test heads/frotz tags/frotz &&
309         if git push testrepo master:frotz
310         then
311                 echo "Oops, should have failed"
312                 false
313         else
314                 check_push_result $the_first_commit heads/frotz tags/frotz
315         fi
316
317 '
318
319 test_expect_success 'push with colon-less refspec (1)' '
320
321         mk_test heads/frotz tags/frotz &&
322         git branch -f frotz master &&
323         git push testrepo frotz &&
324         check_push_result $the_commit heads/frotz &&
325         check_push_result $the_first_commit tags/frotz
326
327 '
328
329 test_expect_success 'push with colon-less refspec (2)' '
330
331         mk_test heads/frotz tags/frotz &&
332         if git show-ref --verify -q refs/heads/frotz
333         then
334                 git branch -D frotz
335         fi &&
336         git tag -f frotz &&
337         git push testrepo frotz &&
338         check_push_result $the_commit tags/frotz &&
339         check_push_result $the_first_commit heads/frotz
340
341 '
342
343 test_expect_success 'push with colon-less refspec (3)' '
344
345         mk_test &&
346         if git show-ref --verify -q refs/tags/frotz
347         then
348                 git tag -d frotz
349         fi &&
350         git branch -f frotz master &&
351         git push testrepo frotz &&
352         check_push_result $the_commit heads/frotz &&
353         test 1 = $( cd testrepo && git show-ref | wc -l )
354 '
355
356 test_expect_success 'push with colon-less refspec (4)' '
357
358         mk_test &&
359         if git show-ref --verify -q refs/heads/frotz
360         then
361                 git branch -D frotz
362         fi &&
363         git tag -f frotz &&
364         git push testrepo frotz &&
365         check_push_result $the_commit tags/frotz &&
366         test 1 = $( cd testrepo && git show-ref | wc -l )
367
368 '
369
370 test_expect_success 'push head with non-existent, incomplete dest' '
371
372         mk_test &&
373         git push testrepo master:branch &&
374         check_push_result $the_commit heads/branch
375
376 '
377
378 test_expect_success 'push tag with non-existent, incomplete dest' '
379
380         mk_test &&
381         git tag -f v1.0 &&
382         git push testrepo v1.0:tag &&
383         check_push_result $the_commit tags/tag
384
385 '
386
387 test_expect_success 'push sha1 with non-existent, incomplete dest' '
388
389         mk_test &&
390         test_must_fail git push testrepo `git rev-parse master`:foo
391
392 '
393
394 test_expect_success 'push ref expression with non-existent, incomplete dest' '
395
396         mk_test &&
397         test_must_fail git push testrepo master^:branch
398
399 '
400
401 test_expect_success 'push with HEAD' '
402
403         mk_test heads/master &&
404         git checkout master &&
405         git push testrepo HEAD &&
406         check_push_result $the_commit heads/master
407
408 '
409
410 test_expect_success 'push with HEAD nonexisting at remote' '
411
412         mk_test heads/master &&
413         git checkout -b local master &&
414         git push testrepo HEAD &&
415         check_push_result $the_commit heads/local
416 '
417
418 test_expect_success 'push with +HEAD' '
419
420         mk_test heads/master &&
421         git checkout master &&
422         git branch -D local &&
423         git checkout -b local &&
424         git push testrepo master local &&
425         check_push_result $the_commit heads/master &&
426         check_push_result $the_commit heads/local &&
427
428         # Without force rewinding should fail
429         git reset --hard HEAD^ &&
430         test_must_fail git push testrepo HEAD &&
431         check_push_result $the_commit heads/local &&
432
433         # With force rewinding should succeed
434         git push testrepo +HEAD &&
435         check_push_result $the_first_commit heads/local
436
437 '
438
439 test_expect_success 'push HEAD with non-existent, incomplete dest' '
440
441         mk_test &&
442         git checkout master &&
443         git push testrepo HEAD:branch &&
444         check_push_result $the_commit heads/branch
445
446 '
447
448 test_expect_success 'push with config remote.*.push = HEAD' '
449
450         mk_test heads/local &&
451         git checkout master &&
452         git branch -f local $the_commit &&
453         (
454                 cd testrepo &&
455                 git checkout local &&
456                 git reset --hard $the_first_commit
457         ) &&
458         git config remote.there.url testrepo &&
459         git config remote.there.push HEAD &&
460         git config branch.master.remote there &&
461         git push &&
462         check_push_result $the_commit heads/master &&
463         check_push_result $the_first_commit heads/local
464 '
465
466 # clean up the cruft left with the previous one
467 git config --remove-section remote.there
468 git config --remove-section branch.master
469
470 test_expect_success 'push with config remote.*.pushurl' '
471
472         mk_test heads/master &&
473         git checkout master &&
474         git config remote.there.url test2repo &&
475         git config remote.there.pushurl testrepo &&
476         git push there &&
477         check_push_result $the_commit heads/master
478 '
479
480 # clean up the cruft left with the previous one
481 git config --remove-section remote.there
482
483 test_expect_success 'push with dry-run' '
484
485         mk_test heads/master &&
486         (
487                 cd testrepo &&
488                 old_commit=$(git show-ref -s --verify refs/heads/master)
489         ) &&
490         git push --dry-run testrepo &&
491         check_push_result $old_commit heads/master
492 '
493
494 test_expect_success 'push updates local refs' '
495
496         mk_test heads/master &&
497         mk_child child &&
498         (
499                 cd child &&
500                 git pull .. master &&
501                 git push &&
502                 test $(git rev-parse master) = \
503                         $(git rev-parse remotes/origin/master)
504         )
505
506 '
507
508 test_expect_success 'push updates up-to-date local refs' '
509
510         mk_test heads/master &&
511         mk_child child1 &&
512         mk_child child2 &&
513         (cd child1 && git pull .. master && git push) &&
514         (
515                 cd child2 &&
516                 git pull ../child1 master &&
517                 git push &&
518                 test $(git rev-parse master) = \
519                         $(git rev-parse remotes/origin/master)
520         )
521
522 '
523
524 test_expect_success 'push preserves up-to-date packed refs' '
525
526         mk_test heads/master &&
527         mk_child child &&
528         (
529                 cd child &&
530                 git push &&
531                 ! test -f .git/refs/remotes/origin/master
532         )
533
534 '
535
536 test_expect_success 'push does not update local refs on failure' '
537
538         mk_test heads/master &&
539         mk_child child &&
540         mkdir testrepo/.git/hooks &&
541         echo "#!/no/frobnication/today" >testrepo/.git/hooks/pre-receive &&
542         chmod +x testrepo/.git/hooks/pre-receive &&
543         (
544                 cd child &&
545                 git pull .. master
546                 test_must_fail git push &&
547                 test $(git rev-parse master) != \
548                         $(git rev-parse remotes/origin/master)
549         )
550
551 '
552
553 test_expect_success 'allow deleting an invalid remote ref' '
554
555         mk_test heads/master &&
556         rm -f testrepo/.git/objects/??/* &&
557         git push testrepo :refs/heads/master &&
558         (cd testrepo && test_must_fail git rev-parse --verify refs/heads/master)
559
560 '
561
562 test_expect_success 'allow deleting a ref using --delete' '
563         mk_test heads/master &&
564         (cd testrepo && git config receive.denyDeleteCurrent warn) &&
565         git push testrepo --delete master &&
566         (cd testrepo && test_must_fail git rev-parse --verify refs/heads/master)
567 '
568
569 test_expect_success 'allow deleting a tag using --delete' '
570         mk_test heads/master &&
571         git tag -a -m dummy_message deltag heads/master &&
572         git push testrepo --tags &&
573         (cd testrepo && git rev-parse --verify -q refs/tags/deltag) &&
574         git push testrepo --delete tag deltag &&
575         (cd testrepo && test_must_fail git rev-parse --verify refs/tags/deltag)
576 '
577
578 test_expect_success 'push --delete without args aborts' '
579         mk_test heads/master &&
580         test_must_fail git push testrepo --delete
581 '
582
583 test_expect_success 'push --delete refuses src:dest refspecs' '
584         mk_test heads/master &&
585         test_must_fail git push testrepo --delete master:foo
586 '
587
588 test_expect_success 'warn on push to HEAD of non-bare repository' '
589         mk_test heads/master &&
590         (
591                 cd testrepo &&
592                 git checkout master &&
593                 git config receive.denyCurrentBranch warn
594         ) &&
595         git push testrepo master 2>stderr &&
596         grep "warning: updating the current branch" stderr
597 '
598
599 test_expect_success 'deny push to HEAD of non-bare repository' '
600         mk_test heads/master &&
601         (
602                 cd testrepo &&
603                 git checkout master &&
604                 git config receive.denyCurrentBranch true
605         ) &&
606         test_must_fail git push testrepo master
607 '
608
609 test_expect_success 'allow push to HEAD of bare repository (bare)' '
610         mk_test heads/master &&
611         (
612                 cd testrepo &&
613                 git checkout master &&
614                 git config receive.denyCurrentBranch true &&
615                 git config core.bare true
616         ) &&
617         git push testrepo master 2>stderr &&
618         ! grep "warning: updating the current branch" stderr
619 '
620
621 test_expect_success 'allow push to HEAD of non-bare repository (config)' '
622         mk_test heads/master &&
623         (
624                 cd testrepo &&
625                 git checkout master &&
626                 git config receive.denyCurrentBranch false
627         ) &&
628         git push testrepo master 2>stderr &&
629         ! grep "warning: updating the current branch" stderr
630 '
631
632 test_expect_success 'fetch with branches' '
633         mk_empty &&
634         git branch second $the_first_commit &&
635         git checkout second &&
636         echo ".." > testrepo/.git/branches/branch1 &&
637         (
638                 cd testrepo &&
639                 git fetch branch1 &&
640                 r=$(git show-ref -s --verify refs/heads/branch1) &&
641                 test "z$r" = "z$the_commit" &&
642                 test 1 = $(git for-each-ref refs/heads | wc -l)
643         ) &&
644         git checkout master
645 '
646
647 test_expect_success 'fetch with branches containing #' '
648         mk_empty &&
649         echo "..#second" > testrepo/.git/branches/branch2 &&
650         (
651                 cd testrepo &&
652                 git fetch branch2 &&
653                 r=$(git show-ref -s --verify refs/heads/branch2) &&
654                 test "z$r" = "z$the_first_commit" &&
655                 test 1 = $(git for-each-ref refs/heads | wc -l)
656         ) &&
657         git checkout master
658 '
659
660 test_expect_success 'push with branches' '
661         mk_empty &&
662         git checkout second &&
663         echo "testrepo" > .git/branches/branch1 &&
664         git push branch1 &&
665         (
666                 cd testrepo &&
667                 r=$(git show-ref -s --verify refs/heads/master) &&
668                 test "z$r" = "z$the_first_commit" &&
669                 test 1 = $(git for-each-ref refs/heads | wc -l)
670         )
671 '
672
673 test_expect_success 'push with branches containing #' '
674         mk_empty &&
675         echo "testrepo#branch3" > .git/branches/branch2 &&
676         git push branch2 &&
677         (
678                 cd testrepo &&
679                 r=$(git show-ref -s --verify refs/heads/branch3) &&
680                 test "z$r" = "z$the_first_commit" &&
681                 test 1 = $(git for-each-ref refs/heads | wc -l)
682         ) &&
683         git checkout master
684 '
685
686 test_expect_success 'push into aliased refs (consistent)' '
687         mk_test heads/master &&
688         mk_child child1 &&
689         mk_child child2 &&
690         (
691                 cd child1 &&
692                 git branch foo &&
693                 git symbolic-ref refs/heads/bar refs/heads/foo
694                 git config receive.denyCurrentBranch false
695         ) &&
696         (
697                 cd child2 &&
698                 >path2 &&
699                 git add path2 &&
700                 test_tick &&
701                 git commit -a -m child2 &&
702                 git branch foo &&
703                 git branch bar &&
704                 git push ../child1 foo bar
705         )
706 '
707
708 test_expect_success 'push into aliased refs (inconsistent)' '
709         mk_test heads/master &&
710         mk_child child1 &&
711         mk_child child2 &&
712         (
713                 cd child1 &&
714                 git branch foo &&
715                 git symbolic-ref refs/heads/bar refs/heads/foo
716                 git config receive.denyCurrentBranch false
717         ) &&
718         (
719                 cd child2 &&
720                 >path2 &&
721                 git add path2 &&
722                 test_tick &&
723                 git commit -a -m child2 &&
724                 git branch foo &&
725                 >path3 &&
726                 git add path3 &&
727                 test_tick &&
728                 git commit -a -m child2 &&
729                 git branch bar &&
730                 test_must_fail git push ../child1 foo bar 2>stderr &&
731                 grep "refusing inconsistent update" stderr
732         )
733 '
734
735 test_expect_success 'push --porcelain' '
736         mk_empty &&
737         echo >.git/foo  "To testrepo" &&
738         echo >>.git/foo "*      refs/heads/master:refs/remotes/origin/master    [new branch]"  &&
739         echo >>.git/foo "Done" &&
740         git push >.git/bar --porcelain  testrepo refs/heads/master:refs/remotes/origin/master &&
741         (
742                 cd testrepo &&
743                 r=$(git show-ref -s --verify refs/remotes/origin/master) &&
744                 test "z$r" = "z$the_commit" &&
745                 test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
746         ) &&
747         test_cmp .git/foo .git/bar
748 '
749
750 test_expect_success 'push --porcelain bad url' '
751         mk_empty &&
752         test_must_fail git push >.git/bar --porcelain asdfasdfasd refs/heads/master:refs/remotes/origin/master &&
753         test_must_fail grep -q Done .git/bar
754 '
755
756 test_expect_success 'push --porcelain rejected' '
757         mk_empty &&
758         git push testrepo refs/heads/master:refs/remotes/origin/master &&
759         (cd testrepo &&
760                 git reset --hard origin/master^
761                 git config receive.denyCurrentBranch true) &&
762
763         echo >.git/foo  "To testrepo"  &&
764         echo >>.git/foo "!      refs/heads/master:refs/heads/master     [remote rejected] (branch is currently checked out)" &&
765
766         test_must_fail git push >.git/bar --porcelain  testrepo refs/heads/master:refs/heads/master &&
767         test_cmp .git/foo .git/bar
768 '
769
770 test_expect_success 'push --porcelain --dry-run rejected' '
771         mk_empty &&
772         git push testrepo refs/heads/master:refs/remotes/origin/master &&
773         (cd testrepo &&
774                 git reset --hard origin/master
775                 git config receive.denyCurrentBranch true) &&
776
777         echo >.git/foo  "To testrepo"  &&
778         echo >>.git/foo "!      refs/heads/master^:refs/heads/master    [rejected] (non-fast-forward)" &&
779         echo >>.git/foo "Done" &&
780
781         test_must_fail git push >.git/bar --porcelain  --dry-run testrepo refs/heads/master^:refs/heads/master &&
782         test_cmp .git/foo .git/bar
783 '
784
785 test_done