Merge branch 'ad/cygwin-no-backslashes-in-paths'
[alt-git.git] / t / t5500-fetch-pack.sh
blob8a5d3492c713b8ca5eceef13ed55f7bd49edcae9
1 #!/bin/sh
3 # Copyright (c) 2005 Johannes Schindelin
6 test_description='Testing multi_ack pack fetching'
8 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
9 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
11 . ./test-lib.sh
13 # Test fetch-pack/upload-pack pair.
15 # Some convenience functions
17 add () {
18 name=$1 &&
19 text="$@" &&
20 branch=$(echo $name | sed -e 's/^\(.\).*$/\1/') &&
21 parents="" &&
23 shift &&
24 while test $1; do
25 parents="$parents -p $1" &&
26 shift
27 done &&
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
40 pull_to_client () {
41 number=$1 &&
42 heads=$2 &&
43 count=$3 &&
44 test_expect_success "$number pull" '
46 cd client &&
47 git fetch-pack -k -v .. $heads &&
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 &&
57 git symbolic-ref HEAD refs/heads/$(
58 echo $heads |
59 sed -e "s/^\(.\).*$/\1/"
60 ) &&
62 git fsck --full &&
64 mv .git/objects/pack/pack-* . &&
65 p=$(ls -1 pack-*.pack) &&
66 git unpack-objects <$p &&
67 git fsck --full &&
69 idx=$(echo pack-*.idx) &&
70 pack_count=$(git show-index <$idx | wc -l) &&
71 test $pack_count = $count &&
72 rm -f pack-*
77 # Here begins the actual testing
79 # A1 - ... - A20 - A21
80 # \
81 # B1 - B2 - .. - B70
83 # client pulls A20, B1. Then tracks only B. Then pulls A.
85 test_expect_success 'setup' '
86 mkdir client &&
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))
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
106 pull_to_client 1st "refs/heads/B refs/heads/A" $((11*3))
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))
116 done
119 pull_to_client 2nd "refs/heads/B" $((64*3))
121 pull_to_client 3rd "refs/heads/A" $((1*3))
123 test_expect_success 'single branch clone' '
124 git clone --single-branch "file://$(pwd)/." singlebranch
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
134 test_expect_success 'single given branch clone' '
135 git clone --single-branch --branch A "file://$(pwd)/." branch-a &&
136 test_must_fail git --git-dir=branch-a/.git rev-parse origin/B
139 test_expect_success 'clone shallow depth 1' '
140 git clone --no-single-branch --depth 1 "file://$(pwd)/." shallow0 &&
141 test "$(git --git-dir=shallow0/.git rev-list --count HEAD)" = 1
144 test_expect_success 'clone shallow depth 1 with fsck' '
145 git config --global fetch.fsckobjects true &&
146 git clone --no-single-branch --depth 1 "file://$(pwd)/." shallow0fsck &&
147 test "$(git --git-dir=shallow0fsck/.git rev-list --count HEAD)" = 1 &&
148 git config --global --unset fetch.fsckobjects
151 test_expect_success 'clone shallow' '
152 git clone --no-single-branch --depth 2 "file://$(pwd)/." shallow
155 test_expect_success 'clone shallow depth count' '
156 test "$(git --git-dir=shallow/.git rev-list --count HEAD)" = 2
159 test_expect_success 'clone shallow object count' '
161 cd shallow &&
162 git count-objects -v
163 ) > count.shallow &&
164 grep "^in-pack: 12" count.shallow
167 test_expect_success 'clone shallow object count (part 2)' '
168 sed -e "/^in-pack:/d" -e "/^packs:/d" -e "/^size-pack:/d" \
169 -e "/: 0$/d" count.shallow > count_output &&
170 test_must_be_empty count_output
173 test_expect_success 'fsck in shallow repo' '
175 cd shallow &&
176 git fsck --full
180 test_expect_success 'simple fetch in shallow repo' '
182 cd shallow &&
183 git fetch
187 test_expect_success 'no changes expected' '
189 cd shallow &&
190 git count-objects -v
191 ) > count.shallow.2 &&
192 cmp count.shallow count.shallow.2
195 test_expect_success 'fetch same depth in shallow repo' '
197 cd shallow &&
198 git fetch --depth=2
202 test_expect_success 'no changes expected' '
204 cd shallow &&
205 git count-objects -v
206 ) > count.shallow.3 &&
207 cmp count.shallow count.shallow.3
210 test_expect_success 'add two more' '
211 add B66 $B65 &&
212 add B67 $B66
215 test_expect_success 'pull in shallow repo' '
217 cd shallow &&
218 git pull .. B
222 test_expect_success 'clone shallow object count' '
224 cd shallow &&
225 git count-objects -v
226 ) > count.shallow &&
227 grep "^count: 6" count.shallow
230 test_expect_success 'add two more (part 2)' '
231 add B68 $B67 &&
232 add B69 $B68
235 test_expect_success 'deepening pull in shallow repo' '
237 cd shallow &&
238 git pull --depth 4 .. B
242 test_expect_success 'clone shallow object count' '
244 cd shallow &&
245 git count-objects -v
246 ) > count.shallow &&
247 grep "^count: 12" count.shallow
250 test_expect_success 'deepening fetch in shallow repo' '
252 cd shallow &&
253 git fetch --depth 4 .. A:A
257 test_expect_success 'clone shallow object count' '
259 cd shallow &&
260 git count-objects -v
261 ) > count.shallow &&
262 grep "^count: 18" count.shallow
265 test_expect_success 'pull in shallow repo with missing merge base' '
267 cd shallow &&
268 git fetch --depth 4 .. A &&
269 test_must_fail git merge --allow-unrelated-histories FETCH_HEAD
273 test_expect_success 'additional simple shallow deepenings' '
275 cd shallow &&
276 git fetch --depth=8 &&
277 git fetch --depth=10 &&
278 git fetch --depth=11
282 test_expect_success 'clone shallow depth count' '
283 test "$(git --git-dir=shallow/.git rev-list --count HEAD)" = 11
286 test_expect_success 'clone shallow object count' '
288 cd shallow &&
289 git prune &&
290 git count-objects -v
291 ) > count.shallow &&
292 grep "^count: 54" count.shallow
295 test_expect_success 'fetch --no-shallow on full repo' '
296 test_must_fail git fetch --noshallow
299 test_expect_success 'fetch --depth --no-shallow' '
301 cd shallow &&
302 test_must_fail git fetch --depth=1 --noshallow
306 test_expect_success 'turn shallow to complete repository' '
308 cd shallow &&
309 git fetch --unshallow &&
310 ! test -f .git/shallow &&
311 git fsck --full
315 test_expect_success 'clone shallow without --no-single-branch' '
316 git clone --depth 1 "file://$(pwd)/." shallow2
319 test_expect_success 'clone shallow object count' '
321 cd shallow2 &&
322 git count-objects -v
323 ) > count.shallow2 &&
324 grep "^in-pack: 3" count.shallow2
327 test_expect_success 'clone shallow with --branch' '
328 git clone --depth 1 --branch A "file://$(pwd)/." shallow3
331 test_expect_success 'clone shallow object count' '
332 echo "in-pack: 3" > count3.expected &&
333 GIT_DIR=shallow3/.git git count-objects -v |
334 grep "^in-pack" > count3.actual &&
335 test_cmp count3.expected count3.actual
338 test_expect_success 'clone shallow with detached HEAD' '
339 git checkout HEAD^ &&
340 git clone --depth 1 "file://$(pwd)/." shallow5 &&
341 git checkout - &&
342 GIT_DIR=shallow5/.git git rev-parse HEAD >actual &&
343 git rev-parse HEAD^ >expected &&
344 test_cmp expected actual
347 test_expect_success 'shallow clone pulling tags' '
348 git tag -a -m A TAGA1 A &&
349 git tag -a -m B TAGB1 B &&
350 git tag TAGA2 A &&
351 git tag TAGB2 B &&
352 git clone --depth 1 "file://$(pwd)/." shallow6 &&
354 cat >taglist.expected <<\EOF &&
355 TAGB1
356 TAGB2
358 GIT_DIR=shallow6/.git git tag -l >taglist.actual &&
359 test_cmp taglist.expected taglist.actual &&
361 echo "in-pack: 4" > count6.expected &&
362 GIT_DIR=shallow6/.git git count-objects -v |
363 grep "^in-pack" > count6.actual &&
364 test_cmp count6.expected count6.actual
367 test_expect_success 'shallow cloning single tag' '
368 git clone --depth 1 --branch=TAGB1 "file://$(pwd)/." shallow7 &&
369 cat >taglist.expected <<\EOF &&
370 TAGB1
371 TAGB2
373 GIT_DIR=shallow7/.git git tag -l >taglist.actual &&
374 test_cmp taglist.expected taglist.actual &&
376 echo "in-pack: 4" > count7.expected &&
377 GIT_DIR=shallow7/.git git count-objects -v |
378 grep "^in-pack" > count7.actual &&
379 test_cmp count7.expected count7.actual
382 test_expect_success 'clone shallow with packed refs' '
383 git pack-refs --all &&
384 git clone --depth 1 --branch A "file://$(pwd)/." shallow8 &&
385 echo "in-pack: 4" > count8.expected &&
386 GIT_DIR=shallow8/.git git count-objects -v |
387 grep "^in-pack" > count8.actual &&
388 test_cmp count8.expected count8.actual
391 test_expect_success 'in_vain not triggered before first ACK' '
392 rm -rf myserver myclient &&
393 git init myserver &&
394 test_commit -C myserver foo &&
395 git clone "file://$(pwd)/myserver" myclient &&
397 # MAX_IN_VAIN is 256. Because of batching, the client will send 496
398 # (16+32+64+128+256) commits, not 256, before giving up. So create 496
399 # irrelevant commits.
400 test_commit_bulk -C myclient 496 &&
402 # The new commit that the client wants to fetch.
403 test_commit -C myserver bar &&
405 git -C myclient fetch --progress origin 2>log &&
406 test_i18ngrep "remote: Total 3 " log
409 test_expect_success 'in_vain resetted upon ACK' '
410 rm -rf myserver myclient &&
411 git init myserver &&
413 # Linked list of commits on main. The first is common; the rest are
414 # not.
415 test_commit -C myserver first_main_commit &&
416 git clone "file://$(pwd)/myserver" myclient &&
417 test_commit_bulk -C myclient 255 &&
419 # Another linked list of commits on anotherbranch with no connection to
420 # main. The first is common; the rest are not.
421 git -C myserver checkout --orphan anotherbranch &&
422 test_commit -C myserver first_anotherbranch_commit &&
423 git -C myclient fetch origin anotherbranch:refs/heads/anotherbranch &&
424 git -C myclient checkout anotherbranch &&
425 test_commit_bulk -C myclient 255 &&
427 # The new commit that the client wants to fetch.
428 git -C myserver checkout main &&
429 test_commit -C myserver to_fetch &&
431 # The client will send (as "have"s) all 256 commits in anotherbranch
432 # first. The 256th commit is common between the client and the server,
433 # and should reset in_vain. This allows negotiation to continue until
434 # the client reports that first_anotherbranch_commit is common.
435 git -C myclient fetch --progress origin main 2>log &&
436 test_i18ngrep "Total 3 " log
439 test_expect_success 'fetch in shallow repo unreachable shallow objects' '
441 git clone --bare --branch B --single-branch "file://$(pwd)/." no-reflog &&
442 git clone --depth 1 "file://$(pwd)/no-reflog" shallow9 &&
443 cd no-reflog &&
444 git tag -d TAGB1 TAGB2 &&
445 git update-ref refs/heads/B B~~ &&
446 git gc --prune=now &&
447 cd ../shallow9 &&
448 git fetch origin &&
449 git fsck --no-dangling
452 test_expect_success 'fetch creating new shallow root' '
454 git clone "file://$(pwd)/." shallow10 &&
455 git commit --allow-empty -m empty &&
456 cd shallow10 &&
457 git fetch --depth=1 --progress 2>actual &&
458 # This should fetch only the empty commit, no tree or
459 # blob objects
460 test_i18ngrep "remote: Total 1" actual
464 test_expect_success 'setup tests for the --stdin parameter' '
465 for head in C D E F
467 add $head
468 done &&
469 for head in A B C D E F
471 git tag $head $head
472 done &&
473 cat >input <<-\EOF &&
474 refs/heads/C
475 refs/heads/A
476 refs/heads/D
477 refs/tags/C
478 refs/heads/B
479 refs/tags/A
480 refs/heads/E
481 refs/tags/B
482 refs/tags/E
483 refs/tags/D
485 sort <input >expect &&
487 echo refs/heads/E &&
488 echo refs/tags/E &&
489 cat input
490 ) >input.dup
493 test_expect_success 'setup fetch refs from cmdline v[12]' '
494 cp -r client client0 &&
495 cp -r client client1 &&
496 cp -r client client2
499 for version in '' 0 1 2
501 test_expect_success "protocol.version=$version fetch refs from cmdline" "
503 cd client$version &&
504 GIT_TEST_PROTOCOL_VERSION=$version git fetch-pack --no-progress .. \$(cat ../input)
505 ) >output &&
506 cut -d ' ' -f 2 <output | sort >actual &&
507 test_cmp expect actual
509 done
511 test_expect_success 'fetch refs from stdin' '
513 cd client &&
514 git fetch-pack --stdin --no-progress .. <../input
515 ) >output &&
516 cut -d " " -f 2 <output | sort >actual &&
517 test_cmp expect actual
520 test_expect_success 'fetch mixed refs from cmdline and stdin' '
522 cd client &&
523 tail -n +5 ../input |
524 git fetch-pack --stdin --no-progress .. $(head -n 4 ../input)
525 ) >output &&
526 cut -d " " -f 2 <output | sort >actual &&
527 test_cmp expect actual
530 test_expect_success 'test duplicate refs from stdin' '
532 cd client &&
533 git fetch-pack --stdin --no-progress .. <../input.dup
534 ) >output &&
535 cut -d " " -f 2 <output | sort >actual &&
536 test_cmp expect actual
539 test_expect_success 'set up tests of missing reference' '
540 cat >expect-error <<-\EOF
541 error: no such remote ref refs/heads/xyzzy
545 test_expect_success 'test lonely missing ref' '
547 cd client &&
548 test_must_fail git fetch-pack --no-progress .. refs/heads/xyzzy 2>../error-m
549 ) &&
550 test_cmp expect-error error-m
553 test_expect_success 'test missing ref after existing' '
555 cd client &&
556 test_must_fail git fetch-pack --no-progress .. refs/heads/A refs/heads/xyzzy 2>../error-em
557 ) &&
558 test_cmp expect-error error-em
561 test_expect_success 'test missing ref before existing' '
563 cd client &&
564 test_must_fail git fetch-pack --no-progress .. refs/heads/xyzzy refs/heads/A 2>../error-me
565 ) &&
566 test_cmp expect-error error-me
569 test_expect_success 'test --all, --depth, and explicit head' '
571 cd client &&
572 git fetch-pack --no-progress --all --depth=1 .. refs/heads/A
573 ) >out-adh 2>error-adh
576 test_expect_success 'test --all, --depth, and explicit tag' '
577 git tag OLDTAG refs/heads/B~5 &&
579 cd client &&
580 git fetch-pack --no-progress --all --depth=1 .. refs/tags/OLDTAG
581 ) >out-adt 2>error-adt
584 test_expect_success 'test --all with tag to non-tip' '
585 git commit --allow-empty -m non-tip &&
586 git commit --allow-empty -m tip &&
587 git tag -m "annotated" non-tip HEAD^ &&
589 cd client &&
590 git fetch-pack --all ..
594 test_expect_success 'test --all wrt tag to non-commits' '
595 # create tag-to-{blob,tree,commit,tag}, making sure all tagged objects
596 # are reachable only via created tag references.
597 blob=$(echo "hello blob" | git hash-object -t blob -w --stdin) &&
598 git tag -a -m "tag -> blob" tag-to-blob $blob &&
600 tree=$(printf "100644 blob $blob\tfile" | git mktree) &&
601 git tag -a -m "tag -> tree" tag-to-tree $tree &&
603 tree2=$(printf "100644 blob $blob\tfile2" | git mktree) &&
604 commit=$(git commit-tree -m "hello commit" $tree) &&
605 git tag -a -m "tag -> commit" tag-to-commit $commit &&
607 blob2=$(echo "hello blob2" | git hash-object -t blob -w --stdin) &&
608 tag=$(git mktag <<-EOF
609 object $blob2
610 type blob
611 tag tag-to-blob2
612 tagger author A U Thor <author@example.com> 0 +0000
614 hello tag
616 ) &&
617 git tag -a -m "tag -> tag" tag-to-tag $tag &&
619 # `fetch-pack --all` should succeed fetching all those objects.
620 mkdir fetchall &&
622 cd fetchall &&
623 git init &&
624 git fetch-pack --all .. &&
625 git cat-file blob $blob >/dev/null &&
626 git cat-file tree $tree >/dev/null &&
627 git cat-file commit $commit >/dev/null &&
628 git cat-file tag $tag >/dev/null
632 test_expect_success 'shallow fetch with tags does not break the repository' '
633 mkdir repo1 &&
635 cd repo1 &&
636 git init &&
637 test_commit 1 &&
638 test_commit 2 &&
639 test_commit 3 &&
640 mkdir repo2 &&
641 cd repo2 &&
642 git init &&
643 git fetch --depth=2 ../.git main:branch &&
644 git fsck
648 test_expect_success 'fetch-pack can fetch a raw sha1' '
649 git init hidden &&
651 cd hidden &&
652 test_commit 1 &&
653 test_commit 2 &&
654 git update-ref refs/hidden/one HEAD^ &&
655 git config transfer.hiderefs refs/hidden &&
656 git config uploadpack.allowtipsha1inwant true
657 ) &&
658 git fetch-pack hidden $(git -C hidden rev-parse refs/hidden/one)
661 test_expect_success 'fetch-pack can fetch a raw sha1 that is advertised as a ref' '
662 rm -rf server client &&
663 git init server &&
664 test_commit -C server 1 &&
666 git init client &&
667 git -C client fetch-pack ../server \
668 $(git -C server rev-parse refs/heads/main)
671 test_expect_success 'fetch-pack can fetch a raw sha1 overlapping a named ref' '
672 rm -rf server client &&
673 git init server &&
674 test_commit -C server 1 &&
675 test_commit -C server 2 &&
677 git init client &&
678 git -C client fetch-pack ../server \
679 $(git -C server rev-parse refs/tags/1) refs/tags/1
682 test_expect_success 'fetch-pack cannot fetch a raw sha1 that is not advertised as a ref' '
683 rm -rf server &&
685 git init server &&
686 test_commit -C server 5 &&
687 git -C server tag -d 5 &&
688 test_commit -C server 6 &&
690 git init client &&
691 # Some protocol versions (e.g. 2) support fetching
692 # unadvertised objects, so restrict this test to v0.
693 test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 git -C client fetch-pack ../server \
694 $(git -C server rev-parse refs/heads/main^) 2>err &&
695 test_i18ngrep "Server does not allow request for unadvertised object" err
698 check_prot_path () {
699 cat >expected <<-EOF &&
700 Diag: url=$1
701 Diag: protocol=$2
702 Diag: path=$3
704 git fetch-pack --diag-url "$1" | grep -v hostandport= >actual &&
705 test_cmp expected actual
708 check_prot_host_port_path () {
709 case "$2" in
710 *ssh*)
711 pp=ssh
712 uah=userandhost
713 ehost=$(echo $3 | tr -d "[]")
714 diagport="Diag: port=$4"
717 pp=$p
718 uah=hostandport
719 ehost=$(echo $3$4 | sed -e "s/22$/:22/" -e "s/NONE//")
720 diagport=""
722 esac
723 cat >exp <<-EOF &&
724 Diag: url=$1
725 Diag: protocol=$pp
726 Diag: $uah=$ehost
727 $diagport
728 Diag: path=$5
730 grep -v "^$" exp >expected
731 git fetch-pack --diag-url "$1" >actual &&
732 test_cmp expected actual
735 for r in repo re:po re/po
737 # git or ssh with scheme
738 for p in "ssh+git" "git+ssh" git ssh
740 for h in host user@host user@[::1] user@::1
742 for c in "" :
744 test_expect_success "fetch-pack --diag-url $p://$h$c/$r" '
745 check_prot_host_port_path $p://$h/$r $p "$h" NONE "/$r"
747 # "/~" -> "~" conversion
748 test_expect_success "fetch-pack --diag-url $p://$h$c/~$r" '
749 check_prot_host_port_path $p://$h/~$r $p "$h" NONE "~$r"
751 done
752 done
753 for h in host User@host User@[::1]
755 test_expect_success "fetch-pack --diag-url $p://$h:22/$r" '
756 check_prot_host_port_path $p://$h:22/$r $p "$h" 22 "/$r"
758 done
759 done
760 # file with scheme
761 for p in file
763 test_expect_success !MINGW "fetch-pack --diag-url $p://$h/$r" '
764 check_prot_path $p://$h/$r $p "/$r"
766 test_expect_success MINGW "fetch-pack --diag-url $p://$h/$r" '
767 check_prot_path $p://$h/$r $p "//$h/$r"
769 test_expect_success MINGW "fetch-pack --diag-url $p:///$r" '
770 check_prot_path $p:///$r $p "/$r"
772 # No "/~" -> "~" conversion for file
773 test_expect_success !MINGW "fetch-pack --diag-url $p://$h/~$r" '
774 check_prot_path $p://$h/~$r $p "/~$r"
776 test_expect_success MINGW "fetch-pack --diag-url $p://$h/~$r" '
777 check_prot_path $p://$h/~$r $p "//$h/~$r"
779 done
780 # file without scheme
781 for h in nohost nohost:12 [::1] [::1]:23 [ [:aa
783 test_expect_success "fetch-pack --diag-url ./$h:$r" '
784 check_prot_path ./$h:$r $p "./$h:$r"
786 # No "/~" -> "~" conversion for file
787 test_expect_success "fetch-pack --diag-url ./$p:$h/~$r" '
788 check_prot_path ./$p:$h/~$r $p "./$p:$h/~$r"
790 done
791 #ssh without scheme
792 p=ssh
793 for h in host [::1]
795 test_expect_success "fetch-pack --diag-url $h:$r" '
796 check_prot_host_port_path $h:$r $p "$h" NONE "$r"
798 # Do "/~" -> "~" conversion
799 test_expect_success "fetch-pack --diag-url $h:/~$r" '
800 check_prot_host_port_path $h:/~$r $p "$h" NONE "~$r"
802 done
803 done
805 test_expect_success MINGW 'fetch-pack --diag-url file://c:/repo' '
806 check_prot_path file://c:/repo file c:/repo
808 test_expect_success MINGW 'fetch-pack --diag-url c:repo' '
809 check_prot_path c:repo file c:repo
812 test_expect_success 'clone shallow since ...' '
813 test_create_repo shallow-since &&
815 cd shallow-since &&
816 GIT_COMMITTER_DATE="100000000 +0700" git commit --allow-empty -m one &&
817 GIT_COMMITTER_DATE="200000000 +0700" git commit --allow-empty -m two &&
818 GIT_COMMITTER_DATE="300000000 +0700" git commit --allow-empty -m three &&
819 git clone --shallow-since "300000000 +0700" "file://$(pwd)/." ../shallow11 &&
820 git -C ../shallow11 log --pretty=tformat:%s HEAD >actual &&
821 echo three >expected &&
822 test_cmp expected actual
826 test_expect_success 'fetch shallow since ...' '
827 git -C shallow11 fetch --shallow-since "200000000 +0700" origin &&
828 git -C shallow11 log --pretty=tformat:%s origin/main >actual &&
829 cat >expected <<-\EOF &&
830 three
833 test_cmp expected actual
836 test_expect_success 'clone shallow since selects no commits' '
837 test_create_repo shallow-since-the-future &&
839 cd shallow-since-the-future &&
840 GIT_COMMITTER_DATE="100000000 +0700" git commit --allow-empty -m one &&
841 GIT_COMMITTER_DATE="200000000 +0700" git commit --allow-empty -m two &&
842 GIT_COMMITTER_DATE="300000000 +0700" git commit --allow-empty -m three &&
843 test_must_fail git clone --shallow-since "900000000 +0700" "file://$(pwd)/." ../shallow111
847 # A few subtle things about the request in this test:
849 # - the server must have commit-graphs present and enabled
851 # - the history is such that our want/have share a common ancestor ("base"
852 # here)
854 # - we send only a single have, which is fewer than a normal client would
855 # send. This ensures that we don't parse "base" up front with
856 # parse_object(), but rather traverse to it as a parent while deciding if we
857 # can stop the "have" negotiation, and call parse_commit(). The former
858 # sees the actual object data and so always loads the three oid, whereas the
859 # latter will try to load it lazily.
861 # - we must use protocol v2, because it handles the "have" negotiation before
862 # processing the shallow directives
864 test_expect_success 'shallow since with commit graph and already-seen commit' '
865 test_create_repo shallow-since-graph &&
867 cd shallow-since-graph &&
868 test_commit base &&
869 test_commit main &&
870 git checkout -b other HEAD^ &&
871 test_commit other &&
872 git commit-graph write --reachable &&
873 git config core.commitGraph true &&
875 GIT_PROTOCOL=version=2 git upload-pack . <<-EOF >/dev/null
876 0012command=fetch
877 $(echo "object-format=$(test_oid algo)" | packetize)
878 00010013deepen-since 1
879 $(echo "want $(git rev-parse other)" | packetize)
880 $(echo "have $(git rev-parse main)" | packetize)
881 0000
886 test_expect_success 'shallow clone exclude tag two' '
887 test_create_repo shallow-exclude &&
889 cd shallow-exclude &&
890 test_commit one &&
891 test_commit two &&
892 test_commit three &&
893 git clone --shallow-exclude two "file://$(pwd)/." ../shallow12 &&
894 git -C ../shallow12 log --pretty=tformat:%s HEAD >actual &&
895 echo three >expected &&
896 test_cmp expected actual
900 test_expect_success 'fetch exclude tag one' '
901 git -C shallow12 fetch --shallow-exclude one origin &&
902 git -C shallow12 log --pretty=tformat:%s origin/main >actual &&
903 test_write_lines three two >expected &&
904 test_cmp expected actual
907 test_expect_success 'fetching deepen' '
908 test_create_repo shallow-deepen &&
910 cd shallow-deepen &&
911 test_commit one &&
912 test_commit two &&
913 test_commit three &&
914 git clone --depth 1 "file://$(pwd)/." deepen &&
915 test_commit four &&
916 git -C deepen log --pretty=tformat:%s main >actual &&
917 echo three >expected &&
918 test_cmp expected actual &&
919 git -C deepen fetch --deepen=1 &&
920 git -C deepen log --pretty=tformat:%s origin/main >actual &&
921 cat >expected <<-\EOF &&
922 four
923 three
926 test_cmp expected actual
930 test_expect_success 'use ref advertisement to prune "have" lines sent' '
931 rm -rf server client &&
932 git init server &&
933 test_commit -C server both_have_1 &&
934 git -C server tag -d both_have_1 &&
935 test_commit -C server both_have_2 &&
937 git clone server client &&
938 test_commit -C server server_has &&
939 test_commit -C client client_has &&
941 # In both protocol v0 and v2, ensure that the parent of both_have_2 is
942 # not sent as a "have" line. The client should know that the server has
943 # both_have_2, so it only needs to inform the server that it has
944 # both_have_2, and the server can infer the rest.
946 rm -f trace &&
947 cp -r client clientv0 &&
948 GIT_TRACE_PACKET="$(pwd)/trace" git -C clientv0 \
949 fetch origin server_has both_have_2 &&
950 grep "have $(git -C client rev-parse client_has)" trace &&
951 grep "have $(git -C client rev-parse both_have_2)" trace &&
952 ! grep "have $(git -C client rev-parse both_have_2^)" trace &&
954 rm -f trace &&
955 cp -r client clientv2 &&
956 GIT_TRACE_PACKET="$(pwd)/trace" git -C clientv2 -c protocol.version=2 \
957 fetch origin server_has both_have_2 &&
958 grep "have $(git -C client rev-parse client_has)" trace &&
959 grep "have $(git -C client rev-parse both_have_2)" trace &&
960 ! grep "have $(git -C client rev-parse both_have_2^)" trace
963 test_expect_success 'filtering by size' '
964 rm -rf server client &&
965 test_create_repo server &&
966 test_commit -C server one &&
967 test_config -C server uploadpack.allowfilter 1 &&
969 test_create_repo client &&
970 git -C client fetch-pack --filter=blob:limit=0 ../server HEAD &&
972 # Ensure that object is not inadvertently fetched
973 commit=$(git -C server rev-parse HEAD) &&
974 blob=$(git hash-object server/one.t) &&
975 git -C client rev-list --objects --missing=allow-any "$commit" >oids &&
976 ! grep "$blob" oids
979 test_expect_success 'filtering by size has no effect if support for it is not advertised' '
980 rm -rf server client &&
981 test_create_repo server &&
982 test_commit -C server one &&
984 test_create_repo client &&
985 git -C client fetch-pack --filter=blob:limit=0 ../server HEAD 2> err &&
987 # Ensure that object is fetched
988 commit=$(git -C server rev-parse HEAD) &&
989 blob=$(git hash-object server/one.t) &&
990 git -C client rev-list --objects --missing=allow-any "$commit" >oids &&
991 grep "$blob" oids &&
993 test_i18ngrep "filtering not recognized by server" err
996 fetch_filter_blob_limit_zero () {
997 SERVER="$1"
998 URL="$2"
1000 rm -rf "$SERVER" client &&
1001 test_create_repo "$SERVER" &&
1002 test_commit -C "$SERVER" one &&
1003 test_config -C "$SERVER" uploadpack.allowfilter 1 &&
1005 git clone "$URL" client &&
1007 test_commit -C "$SERVER" two &&
1009 git -C client fetch --filter=blob:limit=0 origin HEAD:somewhere &&
1011 # Ensure that commit is fetched, but blob is not
1012 commit=$(git -C "$SERVER" rev-parse two) &&
1013 blob=$(git hash-object server/two.t) &&
1014 git -C client rev-list --objects --missing=allow-any "$commit" >oids &&
1015 grep "$commit" oids &&
1016 ! grep "$blob" oids
1019 test_expect_success 'fetch with --filter=blob:limit=0' '
1020 fetch_filter_blob_limit_zero server server
1023 . "$TEST_DIRECTORY"/lib-httpd.sh
1024 start_httpd
1026 test_expect_success 'fetch with --filter=blob:limit=0 and HTTP' '
1027 fetch_filter_blob_limit_zero "$HTTPD_DOCUMENT_ROOT_PATH/server" "$HTTPD_URL/smart/server"
1030 # DO NOT add non-httpd-specific tests here, because the last part of this
1031 # test script is only executed when httpd is available and enabled.
1033 test_done