Code

Refuse updating the current branch in a non-bare repository via push
[git.git] / t / t5516-fetch-push.sh
1 #!/bin/sh
3 test_description='fetching and pushing, with or without wildcard'
5 . ./test-lib.sh
7 D=`pwd`
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 }
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 }
43 mk_child() {
44         rm -rf "$1" &&
45         git clone testrepo "$1"
46 }
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 }
65 test_expect_success setup '
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) &&
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)
79 '
81 test_expect_success 'fetch without wildcard' '
82         mk_empty &&
83         (
84                 cd testrepo &&
85                 git fetch .. refs/heads/master:refs/remotes/origin/master &&
87                 r=$(git show-ref -s --verify refs/remotes/origin/master) &&
88                 test "z$r" = "z$the_commit" &&
90                 test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
91         )
92 '
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 &&
102                 r=$(git show-ref -s --verify refs/remotes/origin/master) &&
103                 test "z$r" = "z$the_commit" &&
105                 test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
106         )
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 &&
119                 r=$(git show-ref -s --verify refs/remotes/origin/master) &&
120                 test "z$r" = "z$the_commit" &&
122                 test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
123         )
126 test_expect_success 'push without wildcard' '
127         mk_empty &&
129         git push testrepo refs/heads/master:refs/remotes/origin/master &&
130         (
131                 cd testrepo &&
132                 r=$(git show-ref -s --verify refs/remotes/origin/master) &&
133                 test "z$r" = "z$the_commit" &&
135                 test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
136         )
139 test_expect_success 'push with wildcard' '
140         mk_empty &&
142         git push testrepo "refs/heads/*:refs/remotes/origin/*" &&
143         (
144                 cd testrepo &&
145                 r=$(git show-ref -s --verify refs/remotes/origin/master) &&
146                 test "z$r" = "z$the_commit" &&
148                 test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
149         )
152 test_expect_success 'push with insteadOf' '
153         mk_empty &&
154         TRASH="$(pwd)/" &&
155         git config "url.$TRASH.insteadOf" trash/ &&
156         git push trash/testrepo refs/heads/master:refs/remotes/origin/master &&
157         (
158                 cd testrepo &&
159                 r=$(git show-ref -s --verify refs/remotes/origin/master) &&
160                 test "z$r" = "z$the_commit" &&
162                 test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
163         )
166 test_expect_success 'push with matching heads' '
168         mk_test heads/master &&
169         git push testrepo &&
170         check_push_result $the_commit heads/master
174 test_expect_success 'push with matching heads on the command line' '
176         mk_test heads/master &&
177         git push testrepo : &&
178         check_push_result $the_commit heads/master
182 test_expect_success 'failed (non-fast-forward) push with matching heads' '
184         mk_test heads/master &&
185         git push testrepo : &&
186         git commit --amend -massaged &&
187         test_must_fail git push testrepo &&
188         check_push_result $the_commit heads/master &&
189         git reset --hard $the_commit
193 test_expect_success 'push --force with matching heads' '
195         mk_test heads/master &&
196         git push testrepo : &&
197         git commit --amend -massaged &&
198         git push --force testrepo &&
199         ! check_push_result $the_commit heads/master &&
200         git reset --hard $the_commit
204 test_expect_success 'push with matching heads and forced update' '
206         mk_test heads/master &&
207         git push testrepo : &&
208         git commit --amend -massaged &&
209         git push testrepo +: &&
210         ! check_push_result $the_commit heads/master &&
211         git reset --hard $the_commit
215 test_expect_success 'push with no ambiguity (1)' '
217         mk_test heads/master &&
218         git push testrepo master:master &&
219         check_push_result $the_commit heads/master
223 test_expect_success 'push with no ambiguity (2)' '
225         mk_test remotes/origin/master &&
226         git push testrepo master:origin/master &&
227         check_push_result $the_commit remotes/origin/master
231 test_expect_success 'push with colon-less refspec, no ambiguity' '
233         mk_test heads/master heads/t/master &&
234         git branch -f t/master master &&
235         git push testrepo master &&
236         check_push_result $the_commit heads/master &&
237         check_push_result $the_first_commit heads/t/master
241 test_expect_success 'push with weak ambiguity (1)' '
243         mk_test heads/master remotes/origin/master &&
244         git push testrepo master:master &&
245         check_push_result $the_commit heads/master &&
246         check_push_result $the_first_commit remotes/origin/master
250 test_expect_success 'push with weak ambiguity (2)' '
252         mk_test heads/master remotes/origin/master remotes/another/master &&
253         git push testrepo master:master &&
254         check_push_result $the_commit heads/master &&
255         check_push_result $the_first_commit remotes/origin/master remotes/another/master
259 test_expect_success 'push with ambiguity' '
261         mk_test heads/frotz tags/frotz &&
262         if git push testrepo master:frotz
263         then
264                 echo "Oops, should have failed"
265                 false
266         else
267                 check_push_result $the_first_commit heads/frotz tags/frotz
268         fi
272 test_expect_success 'push with colon-less refspec (1)' '
274         mk_test heads/frotz tags/frotz &&
275         git branch -f frotz master &&
276         git push testrepo frotz &&
277         check_push_result $the_commit heads/frotz &&
278         check_push_result $the_first_commit tags/frotz
282 test_expect_success 'push with colon-less refspec (2)' '
284         mk_test heads/frotz tags/frotz &&
285         if git show-ref --verify -q refs/heads/frotz
286         then
287                 git branch -D frotz
288         fi &&
289         git tag -f frotz &&
290         git push testrepo frotz &&
291         check_push_result $the_commit tags/frotz &&
292         check_push_result $the_first_commit heads/frotz
296 test_expect_success 'push with colon-less refspec (3)' '
298         mk_test &&
299         if git show-ref --verify -q refs/tags/frotz
300         then
301                 git tag -d frotz
302         fi &&
303         git branch -f frotz master &&
304         git push testrepo frotz &&
305         check_push_result $the_commit heads/frotz &&
306         test 1 = $( cd testrepo && git show-ref | wc -l )
309 test_expect_success 'push with colon-less refspec (4)' '
311         mk_test &&
312         if git show-ref --verify -q refs/heads/frotz
313         then
314                 git branch -D frotz
315         fi &&
316         git tag -f frotz &&
317         git push testrepo frotz &&
318         check_push_result $the_commit tags/frotz &&
319         test 1 = $( cd testrepo && git show-ref | wc -l )
323 test_expect_success 'push head with non-existant, incomplete dest' '
325         mk_test &&
326         git push testrepo master:branch &&
327         check_push_result $the_commit heads/branch
331 test_expect_success 'push tag with non-existant, incomplete dest' '
333         mk_test &&
334         git tag -f v1.0 &&
335         git push testrepo v1.0:tag &&
336         check_push_result $the_commit tags/tag
340 test_expect_success 'push sha1 with non-existant, incomplete dest' '
342         mk_test &&
343         test_must_fail git push testrepo `git rev-parse master`:foo
347 test_expect_success 'push ref expression with non-existant, incomplete dest' '
349         mk_test &&
350         test_must_fail git push testrepo master^:branch
354 test_expect_success 'push with HEAD' '
356         mk_test heads/master &&
357         git checkout master &&
358         git push testrepo HEAD &&
359         check_push_result $the_commit heads/master
363 test_expect_success 'push with HEAD nonexisting at remote' '
365         mk_test heads/master &&
366         git checkout -b local master &&
367         git push testrepo HEAD &&
368         check_push_result $the_commit heads/local
371 test_expect_success 'push with +HEAD' '
373         mk_test heads/master &&
374         git checkout master &&
375         git branch -D local &&
376         git checkout -b local &&
377         git push testrepo master local &&
378         check_push_result $the_commit heads/master &&
379         check_push_result $the_commit heads/local &&
381         # Without force rewinding should fail
382         git reset --hard HEAD^ &&
383         test_must_fail git push testrepo HEAD &&
384         check_push_result $the_commit heads/local &&
386         # With force rewinding should succeed
387         git push testrepo +HEAD &&
388         check_push_result $the_first_commit heads/local
392 test_expect_success 'push HEAD with non-existant, incomplete dest' '
394         mk_test &&
395         git checkout master &&
396         git push testrepo HEAD:branch &&
397         check_push_result $the_commit heads/branch
401 test_expect_success 'push with config remote.*.push = HEAD' '
403         mk_test heads/local &&
404         git checkout master &&
405         git branch -f local $the_commit &&
406         (
407                 cd testrepo &&
408                 git checkout local &&
409                 git reset --hard $the_first_commit
410         ) &&
411         git config remote.there.url testrepo &&
412         git config remote.there.push HEAD &&
413         git config branch.master.remote there &&
414         git push &&
415         check_push_result $the_commit heads/master &&
416         check_push_result $the_first_commit heads/local
419 # clean up the cruft left with the previous one
420 git config --remove-section remote.there
421 git config --remove-section branch.master
423 test_expect_success 'push with config remote.*.pushurl' '
425         mk_test heads/master &&
426         git checkout master &&
427         git config remote.there.url test2repo &&
428         git config remote.there.pushurl testrepo &&
429         git push there &&
430         check_push_result $the_commit heads/master
433 # clean up the cruft left with the previous one
434 git config --remove-section remote.there
436 test_expect_success 'push with dry-run' '
438         mk_test heads/master &&
439         (cd testrepo &&
440          old_commit=$(git show-ref -s --verify refs/heads/master)) &&
441         git push --dry-run testrepo &&
442         check_push_result $old_commit heads/master
445 test_expect_success 'push updates local refs' '
447         mk_test heads/master &&
448         mk_child child &&
449         (cd child &&
450                 git pull .. master &&
451                 git push &&
452         test $(git rev-parse master) = $(git rev-parse remotes/origin/master))
456 test_expect_success 'push updates up-to-date local refs' '
458         mk_test heads/master &&
459         mk_child child1 &&
460         mk_child child2 &&
461         (cd child1 && git pull .. master && git push) &&
462         (cd child2 &&
463                 git pull ../child1 master &&
464                 git push &&
465         test $(git rev-parse master) = $(git rev-parse remotes/origin/master))
469 test_expect_success 'push preserves up-to-date packed refs' '
471         mk_test heads/master &&
472         mk_child child &&
473         (cd child &&
474                 git push &&
475         ! test -f .git/refs/remotes/origin/master)
479 test_expect_success 'push does not update local refs on failure' '
481         mk_test heads/master &&
482         mk_child child &&
483         mkdir testrepo/.git/hooks &&
484         echo exit 1 >testrepo/.git/hooks/pre-receive &&
485         chmod +x testrepo/.git/hooks/pre-receive &&
486         (cd child &&
487                 git pull .. master
488                 test_must_fail git push &&
489                 test $(git rev-parse master) != \
490                         $(git rev-parse remotes/origin/master))
494 test_expect_success 'allow deleting an invalid remote ref' '
496         mk_test heads/master &&
497         rm -f testrepo/.git/objects/??/* &&
498         git push testrepo :refs/heads/master &&
499         (cd testrepo && test_must_fail git rev-parse --verify refs/heads/master)
503 test_expect_success 'warn on push to HEAD of non-bare repository' '
504         mk_test heads/master
505         (cd testrepo &&
506                 git checkout master &&
507                 git config receive.denyCurrentBranch warn) &&
508         git push testrepo master 2>stderr &&
509         grep "warning: updating the current branch" stderr
512 test_expect_success 'deny push to HEAD of non-bare repository' '
513         mk_test heads/master
514         (cd testrepo &&
515                 git checkout master &&
516                 git config receive.denyCurrentBranch true) &&
517         test_must_fail git push testrepo master
520 test_expect_success 'allow push to HEAD of bare repository (bare)' '
521         mk_test heads/master
522         (cd testrepo &&
523                 git checkout master &&
524                 git config receive.denyCurrentBranch true &&
525                 git config core.bare true) &&
526         git push testrepo master 2>stderr &&
527         ! grep "warning: updating the current branch" stderr
530 test_expect_success 'allow push to HEAD of non-bare repository (config)' '
531         mk_test heads/master
532         (cd testrepo &&
533                 git checkout master &&
534                 git config receive.denyCurrentBranch false
535         ) &&
536         git push testrepo master 2>stderr &&
537         ! grep "warning: updating the current branch" stderr
540 test_expect_success 'fetch with branches' '
541         mk_empty &&
542         git branch second $the_first_commit &&
543         git checkout second &&
544         echo ".." > testrepo/.git/branches/branch1 &&
545         (cd testrepo &&
546                 git fetch branch1 &&
547                 r=$(git show-ref -s --verify refs/heads/branch1) &&
548                 test "z$r" = "z$the_commit" &&
549                 test 1 = $(git for-each-ref refs/heads | wc -l)
550         ) &&
551         git checkout master
554 test_expect_success 'fetch with branches containing #' '
555         mk_empty &&
556         echo "..#second" > testrepo/.git/branches/branch2 &&
557         (cd testrepo &&
558                 git fetch branch2 &&
559                 r=$(git show-ref -s --verify refs/heads/branch2) &&
560                 test "z$r" = "z$the_first_commit" &&
561                 test 1 = $(git for-each-ref refs/heads | wc -l)
562         ) &&
563         git checkout master
566 test_expect_success 'push with branches' '
567         mk_empty &&
568         git checkout second &&
569         echo "testrepo" > .git/branches/branch1 &&
570         git push branch1 &&
571         (cd testrepo &&
572                 r=$(git show-ref -s --verify refs/heads/master) &&
573                 test "z$r" = "z$the_first_commit" &&
574                 test 1 = $(git for-each-ref refs/heads | wc -l)
575         )
578 test_expect_success 'push with branches containing #' '
579         mk_empty &&
580         echo "testrepo#branch3" > .git/branches/branch2 &&
581         git push branch2 &&
582         (cd testrepo &&
583                 r=$(git show-ref -s --verify refs/heads/branch3) &&
584                 test "z$r" = "z$the_first_commit" &&
585                 test 1 = $(git for-each-ref refs/heads | wc -l)
586         ) &&
587         git checkout master
590 test_done