Raw
1 #!/bin/sh
2 #
3 # Copyright (c) 2005 Johannes Schindelin
4 #
5
6 test_description='Testing multi_ack pack fetching'
7
8 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
9 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
10
11 . ./test-lib.sh
12
13 # Test fetch-pack/upload-pack pair.
14
15 # Some convenience functions
16
17 add () {
18 name=$1 &&
19 text="$@" &&
20 branch=$(echo $name | sed -e 's/^\(.\).*$/\1/') &&
21 parents="" &&
22
23 shift &&
24 while test $1; do
25 parents="$parents -p $1" &&
26 shift
27 done &&
28
29 echo "$text" > test.txt &&
30 git update-index --add test.txt &&
31 tree=$(git write-tree) &&
32 # make sure timestamps are in correct order
33 test_tick &&
34 commit=$(echo "$text" | git commit-tree $tree $parents) &&
35 eval "$name=$commit; export $name" &&
36 git update-ref "refs/heads/$branch" "$commit" &&
37 eval ${branch}TIP=$commit
38 }
39
40 pull_to_client () {
41 number=$1 &&
42 heads=$2 &&
43 count=$3 &&
44 test_expect_success "$number pull" '
45 (
46 cd client &&
47 git fetch-pack -k -v .. $heads &&
48
49 case "$heads" in
50 *A*)
51 git update-ref refs/heads/A "$ATIP";;
52 esac &&
53 case "$heads" in *B*)
54 git update-ref refs/heads/B "$BTIP";;
55 esac &&
56
57 git symbolic-ref HEAD refs/heads/$(
58 echo $heads |
59 sed -e "s/^\(.\).*$/\1/"
60 ) &&
61
62 git fsck --full &&
63
64 mv .git/objects/pack/pack-* . &&
65 p=$(ls -1 pack-*.pack) &&
66 git unpack-objects <$p &&
67 git fsck --full &&
68
69 idx=$(echo pack-*.idx) &&
70 pack_count=$(git show-index <$idx | wc -l) &&
71 test $pack_count = $count &&
72 rm -f pack-*
73 )
74 '
75 }
76
77 # Here begins the actual testing
78
79 # A1 - ... - A20 - A21
80 # \
81 # B1 - B2 - .. - B70
82
83 # client pulls A20, B1. Then tracks only B. Then pulls A.
84
85 test_expect_success 'setup' '
86 mkdir client &&
87 (
88 cd client &&
89 git init &&
90 git config transfer.unpacklimit 0
91 ) &&
92 add A1 &&
93 prev=1 &&
94 cur=2 &&
95 while [ $cur -le 10 ]; do
96 add A$cur $(eval echo \$A$prev) &&
97 prev=$cur &&
98 cur=$(($cur+1)) || return 1
99 done &&
100 add B1 $A1 &&
101 git update-ref refs/heads/A "$ATIP" &&
102 git update-ref refs/heads/B "$BTIP" &&
103 git symbolic-ref HEAD refs/heads/B
104 '
105
106 pull_to_client 1st "refs/heads/B refs/heads/A" $((11*3))
107
108 test_expect_success 'post 1st pull setup' '
109 add A11 $A10 &&
110 prev=1 &&
111 cur=2 &&
112 while [ $cur -le 65 ]; do
113 add B$cur $(eval echo \$B$prev) &&
114 prev=$cur &&
115 cur=$(($cur+1)) || return 1
116 done
117 '
118
119 pull_to_client 2nd "refs/heads/B" $((64*3))
120
121 pull_to_client 3rd "refs/heads/A" $((1*3))
122
123 test_expect_success 'single branch clone' '
124 git clone --single-branch "file://$(pwd)/." singlebranch
125 '
126
127 test_expect_success 'single branch object count' '
128 GIT_DIR=singlebranch/.git git count-objects -v |
129 grep "^in-pack:" > count.singlebranch &&
130 echo "in-pack: 198" >expected &&
131 test_cmp expected count.singlebranch
132 '
133
134 test_expect_success 'single given branch clone' '
135 GIT_TRACE2_EVENT="$(pwd)/branch-a/trace2_event" \
136 git clone --single-branch --branch A "file://$(pwd)/." branch-a &&
137 test_must_fail git --git-dir=branch-a/.git rev-parse origin/B &&
138 grep \"fetch-info\".*\"haves\":0 branch-a/trace2_event &&
139 grep \"fetch-info\".*\"wants\":1 branch-a/trace2_event
140 '
141
142 test_expect_success 'clone shallow depth 1' '
143 GIT_TRACE2_EVENT="$(pwd)/shallow0/trace2_event" \
144 git clone --no-single-branch --depth 1 "file://$(pwd)/." shallow0 &&
145 test "$(git --git-dir=shallow0/.git rev-list --count HEAD)" = 1 &&
146 grep \"fetch-info\".*\"depth\":1 shallow0/trace2_event
147 '
148
149 test_expect_success 'clone shallow depth 1 with fsck' '
150 git config --global fetch.fsckobjects true &&
151 git clone --no-single-branch --depth 1 "file://$(pwd)/." shallow0fsck &&
152 test "$(git --git-dir=shallow0fsck/.git rev-list --count HEAD)" = 1 &&
153 git config --global --unset fetch.fsckobjects
154 '
155
156 test_expect_success 'clone shallow' '
157 git clone --no-single-branch --depth 2 "file://$(pwd)/." shallow &&
158 git -C shallow config set maintenance.auto false
159 '
160
161 test_expect_success 'clone shallow depth count' '
162 test "$(git --git-dir=shallow/.git rev-list --count HEAD)" = 2
163 '
164
165 test_expect_success 'clone shallow object count' '
166 (
167 cd shallow &&
168 git count-objects -v
169 ) > count.shallow &&
170 grep "^in-pack: 12" count.shallow
171 '
172
173 test_expect_success 'clone shallow object count (part 2)' '
174 sed -e "/^in-pack:/d" -e "/^packs:/d" -e "/^size-pack:/d" \
175 -e "/: 0$/d" count.shallow > count_output &&
176 test_must_be_empty count_output
177 '
178
179 test_expect_success 'fsck in shallow repo' '
180 (
181 cd shallow &&
182 git fsck --full
183 )
184 '
185
186 test_expect_success 'simple fetch in shallow repo' '
187 (
188 cd shallow &&
189 git fetch
190 )
191 '
192
193 test_expect_success 'no changes expected' '
194 (
195 cd shallow &&
196 git count-objects -v
197 ) > count.shallow.2 &&
198 cmp count.shallow count.shallow.2
199 '
200
201 test_expect_success 'fetch same depth in shallow repo' '
202 (
203 cd shallow &&
204 git fetch --depth=2
205 )
206 '
207
208 test_expect_success 'no changes expected' '
209 (
210 cd shallow &&
211 git count-objects -v
212 ) > count.shallow.3 &&
213 cmp count.shallow count.shallow.3
214 '
215
216 test_expect_success 'add two more' '
217 add B66 $B65 &&
218 add B67 $B66
219 '
220
221 test_expect_success 'pull in shallow repo' '
222 (
223 cd shallow &&
224 git pull .. B
225 )
226 '
227
228 test_expect_success 'clone shallow object count' '
229 (
230 cd shallow &&
231 git count-objects -v
232 ) > count.shallow &&
233 grep "^count: 6" count.shallow
234 '
235
236 test_expect_success 'add two more (part 2)' '
237 add B68 $B67 &&
238 add B69 $B68
239 '
240
241 test_expect_success 'deepening pull in shallow repo' '
242 (
243 cd shallow &&
244 GIT_TRACE2_EVENT="$(pwd)/trace2_event" \
245 git pull --depth 4 .. B &&
246 grep \"fetch-info\".*\"depth\":4 trace2_event &&
247 grep \"fetch-info\".*\"shallows\":2 trace2_event
248 )
249 '
250
251 test_expect_success 'clone shallow object count' '
252 (
253 cd shallow &&
254 git count-objects -v
255 ) > count.shallow &&
256 grep "^count: 12" count.shallow
257 '
258
259 test_expect_success 'deepening fetch in shallow repo' '
260 (
261 cd shallow &&
262 git fetch --depth 4 .. A:A
263 )
264 '
265
266 test_expect_success 'clone shallow object count' '
267 (
268 cd shallow &&
269 git count-objects -v
270 ) > count.shallow &&
271 grep "^count: 18" count.shallow
272 '
273
274 test_expect_success 'pull in shallow repo with missing merge base' '
275 (
276 cd shallow &&
277 git fetch --depth 4 .. A &&
278 test_must_fail git merge --allow-unrelated-histories FETCH_HEAD
279 )
280 '
281
282 test_expect_success 'additional simple shallow deepenings' '
283 (
284 cd shallow &&
285 git fetch --depth=8 &&
286 git fetch --depth=10 &&
287 git fetch --depth=11
288 )
289 '
290
291 test_expect_success 'clone shallow depth count' '
292 test "$(git --git-dir=shallow/.git rev-list --count HEAD)" = 11
293 '
294
295 test_expect_success 'clone shallow object count' '
296 (
297 cd shallow &&
298 git prune &&
299 git count-objects -v
300 ) > count.shallow &&
301 grep "^count: 54" count.shallow
302 '
303
304 test_expect_success 'fetch --no-shallow on full repo' '
305 test_must_fail git fetch --noshallow
306 '
307
308 test_expect_success 'fetch --depth --no-shallow' '
309 (
310 cd shallow &&
311 test_must_fail git fetch --depth=1 --noshallow
312 )
313 '
314
315 test_expect_success 'turn shallow to complete repository' '
316 (
317 cd shallow &&
318 GIT_TRACE2_EVENT="$(pwd)/trace2_event" \
319 git fetch --unshallow &&
320 ! test -f .git/shallow &&
321 git fsck --full &&
322 grep \"fetch-info\".*\"shallows\":2 trace2_event &&
323 grep \"fetch-info\".*\"depth\":2147483647 trace2_event
324 )
325 '
326
327 test_expect_success 'clone shallow without --no-single-branch' '
328 git clone --depth 1 "file://$(pwd)/." shallow2
329 '
330
331 test_expect_success 'clone shallow object count' '
332 (
333 cd shallow2 &&
334 git count-objects -v
335 ) > count.shallow2 &&
336 grep "^in-pack: 3" count.shallow2
337 '
338
339 test_expect_success 'clone shallow with --branch' '
340 git clone --depth 1 --branch A "file://$(pwd)/." shallow3
341 '
342
343 test_expect_success 'clone shallow object count' '
344 echo "in-pack: 3" > count3.expected &&
345 GIT_DIR=shallow3/.git git count-objects -v |
346 grep "^in-pack" > count3.actual &&
347 test_cmp count3.expected count3.actual
348 '
349
350 test_expect_success 'clone shallow with detached HEAD' '
351 git checkout HEAD^ &&
352 git clone --depth 1 "file://$(pwd)/." shallow5 &&
353 git checkout - &&
354 GIT_DIR=shallow5/.git git rev-parse HEAD >actual &&
355 git rev-parse HEAD^ >expected &&
356 test_cmp expected actual
357 '
358
359 test_expect_success 'shallow clone pulling tags' '
360 git tag -a -m A TAGA1 A &&
361 git tag -a -m B TAGB1 B &&
362 git tag TAGA2 A &&
363 git tag TAGB2 B &&
364 git clone --depth 1 "file://$(pwd)/." shallow6 &&
365
366 cat >taglist.expected <<\EOF &&
367 TAGB1
368 TAGB2
369 EOF
370 GIT_DIR=shallow6/.git git tag -l >taglist.actual &&
371 test_cmp taglist.expected taglist.actual &&
372
373 echo "in-pack: 4" > count6.expected &&
374 GIT_DIR=shallow6/.git git count-objects -v |
375 grep "^in-pack" > count6.actual &&
376 test_cmp count6.expected count6.actual
377 '
378
379 test_expect_success 'shallow cloning single tag' '
380 git clone --depth 1 --branch=TAGB1 "file://$(pwd)/." shallow7 &&
381 cat >taglist.expected <<\EOF &&
382 TAGB1
383 TAGB2
384 EOF
385 GIT_DIR=shallow7/.git git tag -l >taglist.actual &&
386 test_cmp taglist.expected taglist.actual &&
387
388 echo "in-pack: 4" > count7.expected &&
389 GIT_DIR=shallow7/.git git count-objects -v |
390 grep "^in-pack" > count7.actual &&
391 test_cmp count7.expected count7.actual
392 '
393
394 test_expect_success 'clone shallow with packed refs' '
395 git pack-refs --all &&
396 git clone --depth 1 --branch A "file://$(pwd)/." shallow8 &&
397 echo "in-pack: 4" > count8.expected &&
398 GIT_DIR=shallow8/.git git count-objects -v |
399 grep "^in-pack" > count8.actual &&
400 test_cmp count8.expected count8.actual
401 '
402
403 test_expect_success 'in_vain not triggered before first ACK' '
404 rm -rf myserver myclient &&
405 git init myserver &&
406 test_commit -C myserver foo &&
407 git clone "file://$(pwd)/myserver" myclient &&
408
409 # MAX_IN_VAIN is 256. Because of batching, the client will send 496
410 # (16+32+64+128+256) commits, not 256, before giving up. So create 496
411 # irrelevant commits.
412 test_commit_bulk -C myclient 496 &&
413
414 # The new commit that the client wants to fetch.
415 test_commit -C myserver bar &&
416
417 git -C myclient fetch --progress origin 2>log &&
418 test_grep "remote: Total 3 " log
419 '
420
421 test_expect_success 'in_vain reset upon ACK' '
422 test_when_finished rm -f log trace2 &&
423 rm -rf myserver myclient &&
424 git init myserver &&
425
426 # Linked list of commits on main. The first is common; the rest are
427 # not.
428 test_commit -C myserver first_main_commit &&
429 git clone "file://$(pwd)/myserver" myclient &&
430 test_commit_bulk -C myclient 255 &&
431
432 # Another linked list of commits on anotherbranch with no connection to
433 # main. The first is common; the rest are not.
434 git -C myserver checkout --orphan anotherbranch &&
435 test_commit -C myserver first_anotherbranch_commit &&
436 git -C myclient fetch origin anotherbranch:refs/heads/anotherbranch &&
437 git -C myclient checkout anotherbranch &&
438 test_commit_bulk -C myclient 255 &&
439
440 # The new commit that the client wants to fetch.
441 git -C myserver checkout main &&
442 test_commit -C myserver to_fetch &&
443
444 # The client will send (as "have"s) all 256 commits in anotherbranch
445 # first. The 256th commit is common between the client and the server,
446 # and should reset in_vain. This allows negotiation to continue until
447 # the client reports that first_anotherbranch_commit is common.
448 GIT_TRACE2_EVENT="$(pwd)/trace2" git -C myclient fetch --progress origin main 2>log &&
449 grep \"key\":\"total_rounds\",\"value\":\"6\" trace2 &&
450 test_grep "Total 3 " log
451 '
452
453 test_expect_success 'fetch in shallow repo unreachable shallow objects' '
454 (
455 git clone --bare --branch B --single-branch "file://$(pwd)/." no-reflog &&
456 git clone --depth 1 "file://$(pwd)/no-reflog" shallow9 &&
457 cd no-reflog &&
458 git tag -d TAGB1 TAGB2 &&
459 git update-ref refs/heads/B B~~ &&
460 git gc --prune=now &&
461 cd ../shallow9 &&
462 git fetch origin &&
463 git fsck --no-dangling
464 )
465 '
466 test_expect_success 'fetch creating new shallow root' '
467 (
468 git clone "file://$(pwd)/." shallow10 &&
469 git commit --allow-empty -m empty &&
470 cd shallow10 &&
471 git fetch --depth=1 --progress 2>actual &&
472 # This should fetch only the empty commit, no tree or
473 # blob objects
474 test_grep "remote: Total 1" actual
475 )
476 '
477
478 test_expect_success 'setup tests for the --stdin parameter' '
479 for head in C D E F
480 do
481 add $head || return 1
482 done &&
483 for head in A B C D E F
484 do
485 git tag $head $head || return 1
486 done &&
487 cat >input <<-\EOF &&
488 refs/heads/C
489 refs/heads/A
490 refs/heads/D
491 refs/tags/C
492 refs/heads/B
493 refs/tags/A
494 refs/heads/E
495 refs/tags/B
496 refs/tags/E
497 refs/tags/D
498 EOF
499 sort <input >expect &&
500 (
501 echo refs/heads/E &&
502 echo refs/tags/E &&
503 cat input
504 ) >input.dup
505 '
506
507 test_expect_success 'setup fetch refs from cmdline v[12]' '
508 cp -r client client0 &&
509 cp -r client client1 &&
510 cp -r client client2
511 '
512
513 for version in '' 0 1 2
514 do
515 test_expect_success "protocol.version=$version fetch refs from cmdline" "
516 (
517 cd client$version &&
518 GIT_TEST_PROTOCOL_VERSION=$version git fetch-pack --no-progress .. \$(cat ../input)
519 ) >output &&
520 cut -d ' ' -f 2 <output | sort >actual &&
521 test_cmp expect actual
522 "
523 done
524
525 test_expect_success 'fetch refs from stdin' '
526 (
527 cd client &&
528 git fetch-pack --stdin --no-progress .. <../input
529 ) >output &&
530 cut -d " " -f 2 <output | sort >actual &&
531 test_cmp expect actual
532 '
533
534 test_expect_success 'fetch mixed refs from cmdline and stdin' '
535 (
536 cd client &&
537 tail -n +5 ../input |
538 git fetch-pack --stdin --no-progress .. $(head -n 4 ../input)
539 ) >output &&
540 cut -d " " -f 2 <output | sort >actual &&
541 test_cmp expect actual
542 '
543
544 test_expect_success 'test duplicate refs from stdin' '
545 (
546 cd client &&
547 git fetch-pack --stdin --no-progress .. <../input.dup
548 ) >output &&
549 cut -d " " -f 2 <output | sort >actual &&
550 test_cmp expect actual
551 '
552
553 test_expect_success 'set up tests of missing reference' '
554 cat >expect-error <<-\EOF
555 error: no such remote ref refs/heads/xyzzy
556 EOF
557 '
558
559 test_expect_success 'test lonely missing ref' '
560 (
561 cd client &&
562 test_must_fail git fetch-pack --no-progress .. refs/heads/xyzzy 2>../error-m
563 ) &&
564 test_cmp expect-error error-m
565 '
566
567 test_expect_success 'test missing ref after existing' '
568 (
569 cd client &&
570 test_must_fail git fetch-pack --no-progress .. refs/heads/A refs/heads/xyzzy 2>../error-em
571 ) &&
572 test_cmp expect-error error-em
573 '
574
575 test_expect_success 'test missing ref before existing' '
576 (
577 cd client &&
578 test_must_fail git fetch-pack --no-progress .. refs/heads/xyzzy refs/heads/A 2>../error-me
579 ) &&
580 test_cmp expect-error error-me
581 '
582
583 test_expect_success 'test --all, --depth, and explicit head' '
584 (
585 cd client &&
586 git fetch-pack --no-progress --all --depth=1 .. refs/heads/A
587 ) >out-adh 2>error-adh
588 '
589
590 test_expect_success 'test --all, --depth, and explicit tag' '
591 git tag OLDTAG refs/heads/B~5 &&
592 (
593 cd client &&
594 git fetch-pack --no-progress --all --depth=1 .. refs/tags/OLDTAG
595 ) >out-adt 2>error-adt
596 '
597
598 test_expect_success 'test --all with tag to non-tip' '
599 git commit --allow-empty -m non-tip &&
600 git commit --allow-empty -m tip &&
601 git tag -m "annotated" non-tip HEAD^ &&
602 (
603 cd client &&
604 git fetch-pack --all ..
605 )
606 '
607
608 test_expect_success 'test --all wrt tag to non-commits' '
609 # create tag-to-{blob,tree,commit,tag}, making sure all tagged objects
610 # are reachable only via created tag references.
611 blob=$(echo "hello blob" | git hash-object -t blob -w --stdin) &&
612 git tag -a -m "tag -> blob" tag-to-blob $blob &&
613
614 tree=$(printf "100644 blob $blob\tfile" | git mktree) &&
615 git tag -a -m "tag -> tree" tag-to-tree $tree &&
616
617 tree2=$(printf "100644 blob $blob\tfile2" | git mktree) &&
618 commit=$(git commit-tree -m "hello commit" $tree) &&
619 git tag -a -m "tag -> commit" tag-to-commit $commit &&
620
621 blob2=$(echo "hello blob2" | git hash-object -t blob -w --stdin) &&
622 tag=$(git mktag <<-EOF
623 object $blob2
624 type blob
625 tag tag-to-blob2
626 tagger author A U Thor <author@example.com> 0 +0000
627
628 hello tag
629 EOF
630 ) &&
631 git tag -a -m "tag -> tag" tag-to-tag $tag &&
632
633 # `fetch-pack --all` should succeed fetching all those objects.
634 mkdir fetchall &&
635 (
636 cd fetchall &&
637 git init &&
638 git fetch-pack --all .. &&
639 git cat-file blob $blob >/dev/null &&
640 git cat-file tree $tree >/dev/null &&
641 git cat-file commit $commit >/dev/null &&
642 git cat-file tag $tag >/dev/null
643 )
644 '
645
646 test_expect_success 'shallow fetch with tags does not break the repository' '
647 mkdir repo1 &&
648 (
649 cd repo1 &&
650 git init &&
651 test_commit 1 &&
652 test_commit 2 &&
653 test_commit 3 &&
654 mkdir repo2 &&
655 cd repo2 &&
656 git init &&
657 git fetch --depth=2 ../.git main:branch &&
658 git fsck
659 )
660 '
661
662 test_expect_success 'fetch-pack can fetch a raw sha1' '
663 git init hidden &&
664 (
665 cd hidden &&
666 test_commit 1 &&
667 test_commit 2 &&
668 git update-ref refs/hidden/one HEAD^ &&
669 git config transfer.hiderefs refs/hidden &&
670 git config uploadpack.allowtipsha1inwant true
671 ) &&
672 git fetch-pack hidden $(git -C hidden rev-parse refs/hidden/one)
673 '
674
675 test_expect_success 'fetch-pack can fetch a raw sha1 that is advertised as a ref' '
676 rm -rf server client &&
677 git init server &&
678 test_commit -C server 1 &&
679
680 git init client &&
681 git -C client fetch-pack ../server \
682 $(git -C server rev-parse refs/heads/main)
683 '
684
685 test_expect_success 'fetch-pack can fetch a raw sha1 overlapping a named ref' '
686 rm -rf server client &&
687 git init server &&
688 test_commit -C server 1 &&
689 test_commit -C server 2 &&
690
691 git init client &&
692 git -C client fetch-pack ../server \
693 $(git -C server rev-parse refs/tags/1) refs/tags/1
694 '
695
696 test_expect_success 'fetch-pack cannot fetch a raw sha1 that is not advertised as a ref' '
697 rm -rf server &&
698
699 git init server &&
700 test_commit -C server 5 &&
701 git -C server tag -d 5 &&
702 test_commit -C server 6 &&
703
704 git init client &&
705 # Some protocol versions (e.g. 2) support fetching
706 # unadvertised objects, so restrict this test to v0.
707 test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 git -C client fetch-pack ../server \
708 $(git -C server rev-parse refs/heads/main^) 2>err &&
709 test_grep "Server does not allow request for unadvertised object" err
710 '
711
712 check_prot_path () {
713 cat >expected <<-EOF &&
714 Diag: url=$1
715 Diag: protocol=$2
716 Diag: path=$3
717 EOF
718 git fetch-pack --diag-url "$1" | grep -v hostandport= >actual &&
719 test_cmp expected actual
720 }
721
722 check_prot_host_port_path () {
723 case "$2" in
724 *ssh*)
725 pp=ssh
726 uah=userandhost
727 ehost=$(echo $3 | tr -d "[]")
728 diagport="Diag: port=$4"
729 ;;
730 *)
731 pp=$p
732 uah=hostandport
733 ehost=$(echo $3$4 | sed -e "s/22$/:22/" -e "s/NONE//")
734 diagport=""
735 ;;
736 esac
737 cat >exp <<-EOF &&
738 Diag: url=$1
739 Diag: protocol=$pp
740 Diag: $uah=$ehost
741 $diagport
742 Diag: path=$5
743 EOF
744 grep -v "^$" exp >expected
745 git fetch-pack --diag-url "$1" >actual &&
746 test_cmp expected actual
747 }
748
749 for r in repo re:po re/po
750 do
751 # git or ssh with scheme
752 for p in "ssh+git" "git+ssh" git ssh
753 do
754 for h in host user@host user@[::1] user@::1
755 do
756 for c in "" :
757 do
758 test_expect_success "fetch-pack --diag-url $p://$h$c/$r" '
759 check_prot_host_port_path $p://$h/$r $p "$h" NONE "/$r"
760 '
761 # "/~" -> "~" conversion
762 test_expect_success "fetch-pack --diag-url $p://$h$c/~$r" '
763 check_prot_host_port_path $p://$h/~$r $p "$h" NONE "~$r"
764 '
765 done
766 done
767 for h in host User@host User@[::1]
768 do
769 test_expect_success "fetch-pack --diag-url $p://$h:22/$r" '
770 check_prot_host_port_path $p://$h:22/$r $p "$h" 22 "/$r"
771 '
772 done
773 done
774 # file with scheme
775 for p in file
776 do
777 test_expect_success !WINDOWS "fetch-pack --diag-url $p://$h/$r" '
778 check_prot_path $p://$h/$r $p "/$r"
779 '
780 test_expect_success MINGW "fetch-pack --diag-url $p://$h/$r" '
781 check_prot_path $p://$h/$r $p "//$h/$r"
782 '
783 test_expect_success MINGW "fetch-pack --diag-url $p:///$r" '
784 check_prot_path $p:///$r $p "/$r"
785 '
786 # No "/~" -> "~" conversion for file
787 test_expect_success !WINDOWS "fetch-pack --diag-url $p://$h/~$r" '
788 check_prot_path $p://$h/~$r $p "/~$r"
789 '
790 test_expect_success MINGW "fetch-pack --diag-url $p://$h/~$r" '
791 check_prot_path $p://$h/~$r $p "//$h/~$r"
792 '
793 done
794 # file without scheme
795 for h in nohost nohost:12 [::1] [::1]:23 [ [:aa
796 do
797 test_expect_success "fetch-pack --diag-url ./$h:$r" '
798 check_prot_path ./$h:$r $p "./$h:$r"
799 '
800 # No "/~" -> "~" conversion for file
801 test_expect_success "fetch-pack --diag-url ./$p:$h/~$r" '
802 check_prot_path ./$p:$h/~$r $p "./$p:$h/~$r"
803 '
804 done
805 #ssh without scheme
806 p=ssh
807 for h in host [::1]
808 do
809 expectation="success"
810 if test_have_prereq CYGWIN && test "$h" = "[::1]"
811 then
812 expectation="failure"
813 fi
814
815 test_expect_$expectation "fetch-pack --diag-url $h:$r" '
816 check_prot_host_port_path $h:$r $p "$h" NONE "$r"
817 '
818 # Do "/~" -> "~" conversion
819 test_expect_$expectation "fetch-pack --diag-url $h:/~$r" '
820 check_prot_host_port_path $h:/~$r $p "$h" NONE "~$r"
821 '
822 done
823 done
824
825 test_expect_success MINGW 'fetch-pack --diag-url file://c:/repo' '
826 check_prot_path file://c:/repo file c:/repo
827 '
828 test_expect_success MINGW 'fetch-pack --diag-url c:repo' '
829 check_prot_path c:repo file c:repo
830 '
831
832 test_expect_success 'clone shallow since ...' '
833 test_create_repo shallow-since &&
834 (
835 cd shallow-since &&
836 GIT_COMMITTER_DATE="100000000 +0700" git commit --allow-empty -m one &&
837 GIT_COMMITTER_DATE="200000000 +0700" git commit --allow-empty -m two &&
838 GIT_COMMITTER_DATE="300000000 +0700" git commit --allow-empty -m three &&
839 git clone --shallow-since "300000000 +0700" "file://$(pwd)/." ../shallow11 &&
840 git -C ../shallow11 log --pretty=tformat:%s HEAD >actual &&
841 echo three >expected &&
842 test_cmp expected actual
843 )
844 '
845
846 test_expect_success 'fetch shallow since ...' '
847 GIT_TRACE2_EVENT=$(pwd)/shallow11/trace2_event \
848 git -C shallow11 fetch --shallow-since "200000000 +0700" origin &&
849 git -C shallow11 log --pretty=tformat:%s origin/main >actual &&
850 cat >expected <<-\EOF &&
851 three
852 two
853 EOF
854 test_cmp expected actual &&
855 grep \"fetch-info\".*\"deepen-since\":true shallow11/trace2_event
856 '
857
858 test_expect_success 'clone shallow since selects no commits' '
859 test_create_repo shallow-since-the-future &&
860 (
861 cd shallow-since-the-future &&
862 GIT_COMMITTER_DATE="100000000 +0700" git commit --allow-empty -m one &&
863 GIT_COMMITTER_DATE="200000000 +0700" git commit --allow-empty -m two &&
864 GIT_COMMITTER_DATE="300000000 +0700" git commit --allow-empty -m three &&
865 test_must_fail git clone --shallow-since "900000000 +0700" "file://$(pwd)/." ../shallow111
866 )
867 '
868
869 # A few subtle things about the request in this test:
870 #
871 # - the server must have commit-graphs present and enabled
872 #
873 # - the history is such that our want/have share a common ancestor ("base"
874 # here)
875 #
876 # - we send only a single have, which is fewer than a normal client would
877 # send. This ensures that we don't parse "base" up front with
878 # parse_object(), but rather traverse to it as a parent while deciding if we
879 # can stop the "have" negotiation, and call parse_commit(). The former
880 # sees the actual object data and so always loads the three oid, whereas the
881 # latter will try to load it lazily.
882 #
883 # - we must use protocol v2, because it handles the "have" negotiation before
884 # processing the shallow directives
885 #
886 test_expect_success 'shallow since with commit graph and already-seen commit' '
887 test_create_repo shallow-since-graph &&
888 (
889 cd shallow-since-graph &&
890 test_commit base &&
891 test_commit main &&
892 git checkout -b other HEAD^ &&
893 test_commit other &&
894 git commit-graph write --reachable &&
895 git config core.commitGraph true &&
896 oid_algo=$(test_oid algo) &&
897 oid_other=$(git rev-parse other) &&
898 oid_main=$(git rev-parse main) &&
899
900 test-tool pkt-line pack >input <<-EOF &&
901 command=fetch
902 object-format=$oid_algo
903 0001
904 deepen-since 1
905 want $oid_other
906 have $oid_main
907 0000
908 EOF
909 GIT_PROTOCOL=version=2 git upload-pack . <input >/dev/null
910 )
911 '
912
913 test_expect_success 'shallow clone exclude tag two' '
914 test_create_repo shallow-exclude &&
915 (
916 cd shallow-exclude &&
917 test_commit one &&
918 test_commit two &&
919 test_commit three &&
920 git clone --shallow-exclude two "file://$(pwd)/." ../shallow12 &&
921 git -C ../shallow12 log --pretty=tformat:%s HEAD >actual &&
922 echo three >expected &&
923 test_cmp expected actual
924 )
925 '
926
927 test_expect_success 'fetch exclude tag one' '
928 git -C shallow12 fetch --shallow-exclude one origin &&
929 git -C shallow12 log --pretty=tformat:%s origin/main >actual &&
930 test_write_lines three two >expected &&
931 test_cmp expected actual
932 '
933
934 test_expect_success 'fetch exclude tag one as revision' '
935 test_when_finished rm -f rev err &&
936 git -C shallow-exclude rev-parse one >rev &&
937 test_must_fail git -C shallow12 fetch --shallow-exclude $(cat rev) origin 2>err &&
938 grep "deepen-not is not a ref:" err
939 '
940
941 test_expect_success 'fetching deepen' '
942 test_create_repo shallow-deepen &&
943 (
944 cd shallow-deepen &&
945 test_commit one &&
946 test_commit two &&
947 test_commit three &&
948 git clone --depth 1 "file://$(pwd)/." deepen &&
949 test_commit four &&
950 git -C deepen log --pretty=tformat:%s main >actual &&
951 echo three >expected &&
952 test_cmp expected actual &&
953 git -C deepen fetch --deepen=1 &&
954 git -C deepen log --pretty=tformat:%s origin/main >actual &&
955 cat >expected <<-\EOF &&
956 four
957 three
958 two
959 EOF
960 test_cmp expected actual
961 )
962 '
963
964 test_expect_success 'fetching deepen beyond merged branch' '
965 test_create_repo shallow-deepen-merged &&
966 (
967 cd shallow-deepen-merged &&
968 git commit --allow-empty -m one &&
969 git commit --allow-empty -m two &&
970 git commit --allow-empty -m three &&
971 git switch -c branch &&
972 git commit --allow-empty -m four &&
973 git commit --allow-empty -m five &&
974 git switch main &&
975 git merge --no-ff branch &&
976 cd - &&
977 git clone --bare --depth 3 "file://$(pwd)/shallow-deepen-merged" deepen.git &&
978 git -C deepen.git fetch origin --deepen=1 &&
979 git -C deepen.git rev-list --all >actual &&
980 for commit in $(sed "/^$/d" deepen.git/shallow)
981 do
982 test_grep "$commit" actual || exit 1
983 done
984 )
985 '
986
987 test_negotiation_algorithm_default () {
988 test_when_finished rm -rf clientv0 clientv2 &&
989 rm -rf server client &&
990 git init server &&
991 test_commit -C server both_have_1 &&
992 git -C server tag -d both_have_1 &&
993 test_commit -C server both_have_2 &&
994
995 git clone server client &&
996 test_commit -C server server_has &&
997 test_commit -C client client_has &&
998
999 # In both protocol v0 and v2, ensure that the parent of both_have_2 is
1000 # not sent as a "have" line. The client should know that the server has
1001 # both_have_2, so it only needs to inform the server that it has
1002 # both_have_2, and the server can infer the rest.
1003
1004 rm -f trace &&
1005 cp -r client clientv0 &&
1006 GIT_TRACE_PACKET="$(pwd)/trace" git -C clientv0 \
1007 "$@" fetch origin server_has both_have_2 &&
1008 grep "have $(git -C client rev-parse client_has)" trace &&
1009 grep "have $(git -C client rev-parse both_have_2)" trace &&
1010 ! grep "have $(git -C client rev-parse both_have_2^)" trace &&
1011
1012 rm -f trace &&
1013 cp -r client clientv2 &&
1014 GIT_TRACE_PACKET="$(pwd)/trace" git -C clientv2 -c protocol.version=2 \
1015 "$@" fetch origin server_has both_have_2 &&
1016 grep "have $(git -C client rev-parse client_has)" trace &&
1017 grep "have $(git -C client rev-parse both_have_2)" trace &&
1018 ! grep "have $(git -C client rev-parse both_have_2^)" trace
1019 }
1020
1021 test_expect_success 'use ref advertisement to prune "have" lines sent' '
1022 test_negotiation_algorithm_default
1023 '
1024
1025 test_expect_success 'same as last but with config overrides' '
1026 test_negotiation_algorithm_default \
1027 -c feature.experimental=true \
1028 -c fetch.negotiationAlgorithm=consecutive
1029 '
1030
1031 test_expect_success 'ensure bogus fetch.negotiationAlgorithm yields error' '
1032 test_when_finished rm -rf clientv0 &&
1033 cp -r client clientv0 &&
1034 test_must_fail git -C clientv0 --fetch.negotiationAlgorithm=bogus \
1035 fetch origin server_has both_have_2
1036 '
1037
1038 test_expect_success 'fetch-pack with fsckObjects and keep-file does not segfault' '
1039 rm -rf server client &&
1040 test_create_repo server &&
1041 test_commit -C server one &&
1042
1043 test_create_repo client &&
1044 git -c fetch.fsckObjects=true \
1045 -C client fetch-pack -k -k ../server HEAD
1046 '
1047
1048 test_expect_success 'filtering by size' '
1049 rm -rf server client &&
1050 test_create_repo server &&
1051 test_commit -C server one &&
1052 test_config -C server uploadpack.allowfilter 1 &&
1053
1054 test_create_repo client &&
1055 GIT_TRACE2_EVENT=$(pwd)/client/trace2_event \
1056 git -C client fetch-pack --filter=blob:limit=0 ../server HEAD &&
1057
1058 # Ensure that object is not inadvertently fetched
1059 commit=$(git -C server rev-parse HEAD) &&
1060 blob=$(git hash-object server/one.t) &&
1061 git -C client rev-list --objects --missing=allow-any "$commit" >oids &&
1062 ! grep "$blob" oids &&
1063
1064 grep \"fetch-info\".*\"filter\":\"blob:limit\" client/trace2_event
1065 '
1066
1067 test_expect_success 'filtering by size has no effect if support for it is not advertised' '
1068 rm -rf server client &&
1069 test_create_repo server &&
1070 test_commit -C server one &&
1071
1072 test_create_repo client &&
1073 git -C client fetch-pack --filter=blob:limit=0 ../server HEAD 2> err &&
1074
1075 # Ensure that object is fetched
1076 commit=$(git -C server rev-parse HEAD) &&
1077 blob=$(git hash-object server/one.t) &&
1078 git -C client rev-list --objects --missing=allow-any "$commit" >oids &&
1079 grep "$blob" oids &&
1080
1081 test_grep "filtering not recognized by server" err
1082 '
1083
1084 fetch_filter_blob_limit_zero () {
1085 SERVER="$1"
1086 URL="$2"
1087
1088 rm -rf "$SERVER" client &&
1089 test_create_repo "$SERVER" &&
1090 test_commit -C "$SERVER" one &&
1091 test_config -C "$SERVER" uploadpack.allowfilter 1 &&
1092
1093 git clone "$URL" client &&
1094
1095 test_commit -C "$SERVER" two &&
1096
1097 git -C client fetch --filter=blob:limit=0 origin HEAD:somewhere &&
1098
1099 # Ensure that commit is fetched, but blob is not
1100 commit=$(git -C "$SERVER" rev-parse two) &&
1101 blob=$(git hash-object "$SERVER/two.t") &&
1102 git -C client rev-list --objects --missing=allow-any "$commit" >oids &&
1103 grep "$commit" oids &&
1104 ! grep "$blob" oids
1105 }
1106
1107 test_expect_success 'fetch with --filter=blob:limit=0' '
1108 fetch_filter_blob_limit_zero server server
1109 '
1110
1111 . "$TEST_DIRECTORY"/lib-httpd.sh
1112 start_httpd
1113
1114 test_expect_success 'fetch with --filter=blob:limit=0 and HTTP' '
1115 fetch_filter_blob_limit_zero "$HTTPD_DOCUMENT_ROOT_PATH/server" "$HTTPD_URL/smart/server"
1116 '
1117
1118 # DO NOT add non-httpd-specific tests here, because the last part of this
1119 # test script is only executed when httpd is available and enabled.
1120
1121 test_done