1#!/bin/sh
2
3test_description='fetching and pushing, with or without wildcard'
4
5. ./test-lib.sh
6
7D=`pwd`
8
9mk_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
20mk_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
43mk_child() {
44 rm -rf "$1" &&
45 git clone testrepo "$1"
46}
47
48check_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
65test_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
81test_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
94test_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
109test_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
126test_expect_success 'push without wildcard' '
127 mk_empty &&
128
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" &&
134
135 test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
136 )
137'
138
139test_expect_success 'push with wildcard' '
140 mk_empty &&
141
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" &&
147
148 test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
149 )
150'
151
152test_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" &&
161
162 test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
163 )
164'
165
166test_expect_success 'push with matching heads' '
167
168 mk_test heads/master &&
169 git push testrepo &&
170 check_push_result $the_commit heads/master
171
172'
173
174test_expect_success 'push with matching heads on the command line' '
175
176 mk_test heads/master &&
177 git push testrepo : &&
178 check_push_result $the_commit heads/master
179
180'
181
182test_expect_success 'failed (non-fast-forward) push with matching heads' '
183
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
190
191'
192
193test_expect_success 'push --force with matching heads' '
194
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
201
202'
203
204test_expect_success 'push with matching heads and forced update' '
205
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
212
213'
214
215test_expect_success 'push with no ambiguity (1)' '
216
217 mk_test heads/master &&
218 git push testrepo master:master &&
219 check_push_result $the_commit heads/master
220
221'
222
223test_expect_success 'push with no ambiguity (2)' '
224
225 mk_test remotes/origin/master &&
226 git push testrepo master:origin/master &&
227 check_push_result $the_commit remotes/origin/master
228
229'
230
231test_expect_success 'push with colon-less refspec, no ambiguity' '
232
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
238
239'
240
241test_expect_success 'push with weak ambiguity (1)' '
242
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
247
248'
249
250test_expect_success 'push with weak ambiguity (2)' '
251
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
256
257'
258
259test_expect_success 'push with ambiguity' '
260
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
269
270'
271
272test_expect_success 'push with colon-less refspec (1)' '
273
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
279
280'
281
282test_expect_success 'push with colon-less refspec (2)' '
283
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
293
294'
295
296test_expect_success 'push with colon-less refspec (3)' '
297
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 )
307'
308
309test_expect_success 'push with colon-less refspec (4)' '
310
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 )
320
321'
322
323test_expect_success 'push head with non-existant, incomplete dest' '
324
325 mk_test &&
326 git push testrepo master:branch &&
327 check_push_result $the_commit heads/branch
328
329'
330
331test_expect_success 'push tag with non-existant, incomplete dest' '
332
333 mk_test &&
334 git tag -f v1.0 &&
335 git push testrepo v1.0:tag &&
336 check_push_result $the_commit tags/tag
337
338'
339
340test_expect_success 'push sha1 with non-existant, incomplete dest' '
341
342 mk_test &&
343 test_must_fail git push testrepo `git rev-parse master`:foo
344
345'
346
347test_expect_success 'push ref expression with non-existant, incomplete dest' '
348
349 mk_test &&
350 test_must_fail git push testrepo master^:branch
351
352'
353
354test_expect_success 'push with HEAD' '
355
356 mk_test heads/master &&
357 git checkout master &&
358 git push testrepo HEAD &&
359 check_push_result $the_commit heads/master
360
361'
362
363test_expect_success 'push with HEAD nonexisting at remote' '
364
365 mk_test heads/master &&
366 git checkout -b local master &&
367 git push testrepo HEAD &&
368 check_push_result $the_commit heads/local
369'
370
371test_expect_success 'push with +HEAD' '
372
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 &&
380
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 &&
385
386 # With force rewinding should succeed
387 git push testrepo +HEAD &&
388 check_push_result $the_first_commit heads/local
389
390'
391
392test_expect_success 'push HEAD with non-existant, incomplete dest' '
393
394 mk_test &&
395 git checkout master &&
396 git push testrepo HEAD:branch &&
397 check_push_result $the_commit heads/branch
398
399'
400
401test_expect_success 'push with config remote.*.push = HEAD' '
402
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
417'
418
419# clean up the cruft left with the previous one
420git config --remove-section remote.there
421git config --remove-section branch.master
422
423test_expect_success 'push with config remote.*.pushurl' '
424
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
431'
432
433# clean up the cruft left with the previous one
434git config --remove-section remote.there
435
436test_expect_success 'push with dry-run' '
437
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
443'
444
445test_expect_success 'push updates local refs' '
446
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))
453
454'
455
456test_expect_success 'push updates up-to-date local refs' '
457
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))
466
467'
468
469test_expect_success 'push preserves up-to-date packed refs' '
470
471 mk_test heads/master &&
472 mk_child child &&
473 (cd child &&
474 git push &&
475 ! test -f .git/refs/remotes/origin/master)
476
477'
478
479test_expect_success 'push does not update local refs on failure' '
480
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))
491
492'
493
494test_expect_success 'allow deleting an invalid remote ref' '
495
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)
500
501'
502
503test_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
510'
511
512test_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
518'
519
520test_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
528'
529
530test_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
538'
539
540test_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
552'
553
554test_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
564'
565
566test_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 )
576'
577
578test_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
588'
589
590test_done