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 mv .git/hooks .git/hooks-disabled
16 )
17}
18
19mk_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
42mk_child() {
43 rm -rf "$1" &&
44 git clone testrepo "$1"
45}
46
47check_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
64test_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
80test_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
93test_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
108test_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
125test_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
142test_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
155test_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
168test_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
182test_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
196test_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
212test_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
220test_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
228test_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
239test_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
250test_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
261test_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
269test_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
277test_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
287test_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
296test_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
305test_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
318test_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
328test_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
342test_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
355test_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
369test_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
377test_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
386test_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
393test_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
400test_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
409test_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
417test_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
438test_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
447test_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
466git config --remove-section remote.there
467git config --remove-section branch.master
468
469test_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
480git config --remove-section remote.there
481
482test_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
491test_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
502test_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
515test_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
525test_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
540test_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
549test_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
558test_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
566test_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
576test_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
586test_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
600test_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
612test_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
624test_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
636test_done