Post 2.46-rc0 batch #1
[git/gitster.git] / t / t5558-clone-bundle-uri.sh
blobcd05321e1764b557466d7057f538675162bccca8
1 #!/bin/sh
3 test_description='test fetching bundles with --bundle-uri'
5 . ./test-lib.sh
6 . "$TEST_DIRECTORY"/lib-bundle.sh
8 test_expect_success 'fail to clone from non-existent file' '
9 test_when_finished rm -rf test &&
10 git clone --bundle-uri="$(pwd)/does-not-exist" . test 2>err &&
11 grep "failed to download bundle from URI" err
14 test_expect_success 'fail to clone from non-bundle file' '
15 test_when_finished rm -rf test &&
16 echo bogus >bogus &&
17 git clone --bundle-uri="$(pwd)/bogus" . test 2>err &&
18 grep "is not a bundle" err
21 test_expect_success 'create bundle' '
22 git init clone-from &&
24 cd clone-from &&
25 git checkout -b topic &&
27 test_commit A &&
28 git bundle create A.bundle topic &&
30 test_commit B &&
31 git bundle create B.bundle topic &&
33 # Create a bundle with reference pointing to non-existent object.
34 commit_a=$(git rev-parse A) &&
35 commit_b=$(git rev-parse B) &&
36 sed -e "/^$/q" -e "s/$commit_a /$commit_b /" \
37 <A.bundle >bad-header.bundle &&
38 convert_bundle_to_pack \
39 <A.bundle >>bad-header.bundle &&
41 tree_b=$(git rev-parse B^{tree}) &&
42 cat >data <<-EOF &&
43 tree $tree_b
44 parent $commit_b
45 author A U Thor
46 committer A U Thor
48 commit: this is a commit with bad emails
50 EOF
51 bad_commit=$(git hash-object --literally -t commit -w --stdin <data) &&
52 git branch bad $bad_commit &&
53 git bundle create bad-object.bundle bad &&
54 git update-ref -d refs/heads/bad
58 test_expect_success 'clone with path bundle' '
59 git clone --bundle-uri="clone-from/B.bundle" \
60 clone-from clone-path &&
61 git -C clone-path rev-parse refs/bundles/topic >actual &&
62 git -C clone-from rev-parse topic >expect &&
63 test_cmp expect actual
66 test_expect_success 'clone with bundle that has bad header' '
67 # Write bundle ref fails, but clone can still proceed.
68 git clone --bundle-uri="clone-from/bad-header.bundle" \
69 clone-from clone-bad-header 2>err &&
70 commit_b=$(git -C clone-from rev-parse B) &&
71 test_grep "trying to write ref '\''refs/bundles/topic'\'' with nonexistent object $commit_b" err &&
72 git -C clone-bad-header for-each-ref --format="%(refname)" >refs &&
73 test_grep ! "refs/bundles/" refs
76 test_expect_success 'clone with bundle that has bad object' '
77 # Unbundle succeeds if no fsckObjects configured.
78 git clone --bundle-uri="clone-from/bad-object.bundle" \
79 clone-from clone-bad-object-no-fsck &&
80 git -C clone-bad-object-no-fsck for-each-ref --format="%(refname)" >refs &&
81 grep "refs/bundles/" refs >actual &&
82 test_write_lines refs/bundles/bad >expect &&
83 test_cmp expect actual &&
85 # Unbundle fails with fsckObjects set true, but clone can still proceed.
86 git -c fetch.fsckObjects=true clone --bundle-uri="clone-from/bad-object.bundle" \
87 clone-from clone-bad-object-fsck 2>err &&
88 test_grep "missingEmail" err &&
89 git -C clone-bad-object-fsck for-each-ref --format="%(refname)" >refs &&
90 test_grep ! "refs/bundles/" refs
93 test_expect_success 'clone with path bundle and non-default hash' '
94 test_when_finished "rm -rf clone-path-non-default-hash" &&
95 GIT_DEFAULT_HASH=sha256 git clone --bundle-uri="clone-from/B.bundle" \
96 clone-from clone-path-non-default-hash &&
97 git -C clone-path-non-default-hash rev-parse refs/bundles/topic >actual &&
98 git -C clone-from rev-parse topic >expect &&
99 test_cmp expect actual
102 test_expect_success 'clone with file:// bundle' '
103 git clone --bundle-uri="file://$(pwd)/clone-from/B.bundle" \
104 clone-from clone-file &&
105 git -C clone-file rev-parse refs/bundles/topic >actual &&
106 git -C clone-from rev-parse topic >expect &&
107 test_cmp expect actual
110 # To get interesting tests for bundle lists, we need to construct a
111 # somewhat-interesting commit history.
113 # ---------------- bundle-4
116 # / \
117 # ----|---|------- bundle-3
118 # | |
119 # | 3
120 # | |
121 # ----|---|------- bundle-2
122 # | |
123 # 2 |
124 # | |
125 # ----|---|------- bundle-1
126 # \ /
129 # (previous commits)
130 test_expect_success 'construct incremental bundle list' '
132 cd clone-from &&
133 git checkout -b base &&
134 test_commit 1 &&
135 git checkout -b left &&
136 test_commit 2 &&
137 git checkout -b right base &&
138 test_commit 3 &&
139 git checkout -b merge left &&
140 git merge right -m "4" &&
142 git bundle create bundle-1.bundle base &&
143 git bundle create bundle-2.bundle base..left &&
144 git bundle create bundle-3.bundle base..right &&
145 git bundle create bundle-4.bundle merge --not left right
149 test_expect_success 'clone bundle list (file, no heuristic)' '
150 cat >bundle-list <<-EOF &&
151 [bundle]
152 version = 1
153 mode = all
155 [bundle "bundle-1"]
156 uri = file://$(pwd)/clone-from/bundle-1.bundle
158 [bundle "bundle-2"]
159 uri = file://$(pwd)/clone-from/bundle-2.bundle
161 [bundle "bundle-3"]
162 uri = file://$(pwd)/clone-from/bundle-3.bundle
164 [bundle "bundle-4"]
165 uri = file://$(pwd)/clone-from/bundle-4.bundle
168 git clone --bundle-uri="file://$(pwd)/bundle-list" \
169 clone-from clone-list-file 2>err &&
170 ! grep "Repository lacks these prerequisite commits" err &&
172 git -C clone-from for-each-ref --format="%(objectname)" >oids &&
173 git -C clone-list-file cat-file --batch-check <oids &&
175 git -C clone-list-file for-each-ref --format="%(refname)" >refs &&
176 grep "refs/bundles/" refs >actual &&
177 cat >expect <<-\EOF &&
178 refs/bundles/base
179 refs/bundles/left
180 refs/bundles/merge
181 refs/bundles/right
183 test_cmp expect actual
186 test_expect_success 'clone bundle list (file, all mode, some failures)' '
187 cat >bundle-list <<-EOF &&
188 [bundle]
189 version = 1
190 mode = all
192 # Does not exist. Should be skipped.
193 [bundle "bundle-0"]
194 uri = file://$(pwd)/clone-from/bundle-0.bundle
196 [bundle "bundle-1"]
197 uri = file://$(pwd)/clone-from/bundle-1.bundle
199 [bundle "bundle-2"]
200 uri = file://$(pwd)/clone-from/bundle-2.bundle
202 # No bundle-3 means bundle-4 will not apply.
204 [bundle "bundle-4"]
205 uri = file://$(pwd)/clone-from/bundle-4.bundle
207 # Does not exist. Should be skipped.
208 [bundle "bundle-5"]
209 uri = file://$(pwd)/clone-from/bundle-5.bundle
212 GIT_TRACE2_PERF=1 \
213 git clone --bundle-uri="file://$(pwd)/bundle-list" \
214 clone-from clone-all-some 2>err &&
215 ! grep "Repository lacks these prerequisite commits" err &&
216 ! grep "fatal" err &&
217 grep "warning: failed to download bundle from URI" err &&
219 git -C clone-from for-each-ref --format="%(objectname)" >oids &&
220 git -C clone-all-some cat-file --batch-check <oids &&
222 git -C clone-all-some for-each-ref --format="%(refname)" >refs &&
223 grep "refs/bundles/" refs >actual &&
224 cat >expect <<-\EOF &&
225 refs/bundles/base
226 refs/bundles/left
228 test_cmp expect actual
231 test_expect_success 'clone bundle list (file, all mode, all failures)' '
232 cat >bundle-list <<-EOF &&
233 [bundle]
234 version = 1
235 mode = all
237 # Does not exist. Should be skipped.
238 [bundle "bundle-0"]
239 uri = file://$(pwd)/clone-from/bundle-0.bundle
241 # Does not exist. Should be skipped.
242 [bundle "bundle-5"]
243 uri = file://$(pwd)/clone-from/bundle-5.bundle
246 git clone --bundle-uri="file://$(pwd)/bundle-list" \
247 clone-from clone-all-fail 2>err &&
248 ! grep "Repository lacks these prerequisite commits" err &&
249 ! grep "fatal" err &&
250 grep "warning: failed to download bundle from URI" err &&
252 git -C clone-from for-each-ref --format="%(objectname)" >oids &&
253 git -C clone-all-fail cat-file --batch-check <oids &&
255 git -C clone-all-fail for-each-ref --format="%(refname)" >refs &&
256 ! grep "refs/bundles/" refs
259 test_expect_success 'clone bundle list (file, any mode)' '
260 cat >bundle-list <<-EOF &&
261 [bundle]
262 version = 1
263 mode = any
265 # Does not exist. Should be skipped.
266 [bundle "bundle-0"]
267 uri = file://$(pwd)/clone-from/bundle-0.bundle
269 [bundle "bundle-1"]
270 uri = file://$(pwd)/clone-from/bundle-1.bundle
272 # Does not exist. Should be skipped.
273 [bundle "bundle-5"]
274 uri = file://$(pwd)/clone-from/bundle-5.bundle
277 git clone --bundle-uri="file://$(pwd)/bundle-list" \
278 clone-from clone-any-file 2>err &&
279 ! grep "Repository lacks these prerequisite commits" err &&
281 git -C clone-from for-each-ref --format="%(objectname)" >oids &&
282 git -C clone-any-file cat-file --batch-check <oids &&
284 git -C clone-any-file for-each-ref --format="%(refname)" >refs &&
285 grep "refs/bundles/" refs >actual &&
286 cat >expect <<-\EOF &&
287 refs/bundles/base
289 test_cmp expect actual
292 test_expect_success 'clone bundle list (file, any mode, all failures)' '
293 cat >bundle-list <<-EOF &&
294 [bundle]
295 version = 1
296 mode = any
298 # Does not exist. Should be skipped.
299 [bundle "bundle-0"]
300 uri = $HTTPD_URL/bundle-0.bundle
302 # Does not exist. Should be skipped.
303 [bundle "bundle-5"]
304 uri = $HTTPD_URL/bundle-5.bundle
307 git clone --bundle-uri="file://$(pwd)/bundle-list" \
308 clone-from clone-any-fail 2>err &&
309 ! grep "fatal" err &&
310 grep "warning: failed to download bundle from URI" err &&
312 git -C clone-from for-each-ref --format="%(objectname)" >oids &&
313 git -C clone-any-fail cat-file --batch-check <oids &&
315 git -C clone-any-fail for-each-ref --format="%(refname)" >refs &&
316 ! grep "refs/bundles/" refs
319 test_expect_success 'negotiation: bundle with part of wanted commits' '
320 test_when_finished "rm -f trace*.txt" &&
321 GIT_TRACE_PACKET="$(pwd)/trace-packet.txt" \
322 git clone --no-local --bundle-uri="clone-from/A.bundle" \
323 clone-from nego-bundle-part &&
324 git -C nego-bundle-part for-each-ref --format="%(refname)" >refs &&
325 grep "refs/bundles/" refs >actual &&
326 test_write_lines refs/bundles/topic >expect &&
327 test_cmp expect actual &&
328 # Ensure that refs/bundles/topic are sent as "have".
329 tip=$(git -C clone-from rev-parse A) &&
330 test_grep "clone> have $tip" trace-packet.txt
333 test_expect_success 'negotiation: bundle with all wanted commits' '
334 test_when_finished "rm -f trace*.txt" &&
335 GIT_TRACE_PACKET="$(pwd)/trace-packet.txt" \
336 git clone --no-local --single-branch --branch=topic --no-tags \
337 --bundle-uri="clone-from/B.bundle" \
338 clone-from nego-bundle-all &&
339 git -C nego-bundle-all for-each-ref --format="%(refname)" >refs &&
340 grep "refs/bundles/" refs >actual &&
341 test_write_lines refs/bundles/topic >expect &&
342 test_cmp expect actual &&
343 # We already have all needed commits so no "want" needed.
344 test_grep ! "clone> want " trace-packet.txt
347 test_expect_success 'negotiation: bundle list (no heuristic)' '
348 test_when_finished "rm -f trace*.txt" &&
349 cat >bundle-list <<-EOF &&
350 [bundle]
351 version = 1
352 mode = all
354 [bundle "bundle-1"]
355 uri = file://$(pwd)/clone-from/bundle-1.bundle
357 [bundle "bundle-2"]
358 uri = file://$(pwd)/clone-from/bundle-2.bundle
361 GIT_TRACE_PACKET="$(pwd)/trace-packet.txt" \
362 git clone --no-local --bundle-uri="file://$(pwd)/bundle-list" \
363 clone-from nego-bundle-list-no-heuristic &&
365 git -C nego-bundle-list-no-heuristic for-each-ref --format="%(refname)" >refs &&
366 grep "refs/bundles/" refs >actual &&
367 cat >expect <<-\EOF &&
368 refs/bundles/base
369 refs/bundles/left
371 test_cmp expect actual &&
372 tip=$(git -C nego-bundle-list-no-heuristic rev-parse refs/bundles/left) &&
373 test_grep "clone> have $tip" trace-packet.txt
376 test_expect_success 'negotiation: bundle list (creationToken)' '
377 test_when_finished "rm -f trace*.txt" &&
378 cat >bundle-list <<-EOF &&
379 [bundle]
380 version = 1
381 mode = all
382 heuristic = creationToken
384 [bundle "bundle-1"]
385 uri = file://$(pwd)/clone-from/bundle-1.bundle
386 creationToken = 1
388 [bundle "bundle-2"]
389 uri = file://$(pwd)/clone-from/bundle-2.bundle
390 creationToken = 2
393 GIT_TRACE_PACKET="$(pwd)/trace-packet.txt" \
394 git clone --no-local --bundle-uri="file://$(pwd)/bundle-list" \
395 clone-from nego-bundle-list-heuristic &&
397 git -C nego-bundle-list-heuristic for-each-ref --format="%(refname)" >refs &&
398 grep "refs/bundles/" refs >actual &&
399 cat >expect <<-\EOF &&
400 refs/bundles/base
401 refs/bundles/left
403 test_cmp expect actual &&
404 tip=$(git -C nego-bundle-list-heuristic rev-parse refs/bundles/left) &&
405 test_grep "clone> have $tip" trace-packet.txt
408 test_expect_success 'negotiation: bundle list with all wanted commits' '
409 test_when_finished "rm -f trace*.txt" &&
410 cat >bundle-list <<-EOF &&
411 [bundle]
412 version = 1
413 mode = all
414 heuristic = creationToken
416 [bundle "bundle-1"]
417 uri = file://$(pwd)/clone-from/bundle-1.bundle
418 creationToken = 1
420 [bundle "bundle-2"]
421 uri = file://$(pwd)/clone-from/bundle-2.bundle
422 creationToken = 2
425 GIT_TRACE_PACKET="$(pwd)/trace-packet.txt" \
426 git clone --no-local --single-branch --branch=left --no-tags \
427 --bundle-uri="file://$(pwd)/bundle-list" \
428 clone-from nego-bundle-list-all &&
430 git -C nego-bundle-list-all for-each-ref --format="%(refname)" >refs &&
431 grep "refs/bundles/" refs >actual &&
432 cat >expect <<-\EOF &&
433 refs/bundles/base
434 refs/bundles/left
436 test_cmp expect actual &&
437 # We already have all needed commits so no "want" needed.
438 test_grep ! "clone> want " trace-packet.txt
441 #########################################################################
442 # HTTP tests begin here
444 . "$TEST_DIRECTORY"/lib-httpd.sh
445 start_httpd
447 test_expect_success 'fail to fetch from non-existent HTTP URL' '
448 test_when_finished rm -rf test &&
449 git clone --bundle-uri="$HTTPD_URL/does-not-exist" . test 2>err &&
450 grep "failed to download bundle from URI" err
453 test_expect_success 'fail to fetch from non-bundle HTTP URL' '
454 test_when_finished rm -rf test &&
455 echo bogus >"$HTTPD_DOCUMENT_ROOT_PATH/bogus" &&
456 git clone --bundle-uri="$HTTPD_URL/bogus" . test 2>err &&
457 grep "is not a bundle" err
460 test_expect_success 'clone HTTP bundle' '
461 cp clone-from/B.bundle "$HTTPD_DOCUMENT_ROOT_PATH/B.bundle" &&
463 git clone --no-local --mirror clone-from \
464 "$HTTPD_DOCUMENT_ROOT_PATH/fetch.git" &&
466 git clone --bundle-uri="$HTTPD_URL/B.bundle" \
467 "$HTTPD_URL/smart/fetch.git" clone-http &&
468 git -C clone-http rev-parse refs/bundles/topic >actual &&
469 git -C clone-from rev-parse topic >expect &&
470 test_cmp expect actual &&
472 test_config -C clone-http log.excludedecoration refs/bundle/
475 test_expect_success 'clone HTTP bundle with non-default hash' '
476 test_when_finished "rm -rf clone-http-non-default-hash" &&
477 GIT_DEFAULT_HASH=sha256 git clone --bundle-uri="$HTTPD_URL/B.bundle" \
478 "$HTTPD_URL/smart/fetch.git" clone-http-non-default-hash &&
479 git -C clone-http-non-default-hash rev-parse refs/bundles/topic >actual &&
480 git -C clone-from rev-parse topic >expect &&
481 test_cmp expect actual
484 test_expect_success 'clone bundle list (HTTP, no heuristic)' '
485 test_when_finished rm -f trace*.txt &&
487 cp clone-from/bundle-*.bundle "$HTTPD_DOCUMENT_ROOT_PATH/" &&
488 cat >"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
489 [bundle]
490 version = 1
491 mode = all
493 [bundle "bundle-1"]
494 uri = $HTTPD_URL/bundle-1.bundle
496 [bundle "bundle-2"]
497 uri = $HTTPD_URL/bundle-2.bundle
499 [bundle "bundle-3"]
500 uri = $HTTPD_URL/bundle-3.bundle
502 [bundle "bundle-4"]
503 uri = $HTTPD_URL/bundle-4.bundle
506 GIT_TRACE2_EVENT="$(pwd)/trace-clone.txt" \
507 git clone --bundle-uri="$HTTPD_URL/bundle-list" \
508 clone-from clone-list-http 2>err &&
509 ! grep "Repository lacks these prerequisite commits" err &&
511 git -C clone-from for-each-ref --format="%(objectname)" >oids &&
512 git -C clone-list-http cat-file --batch-check <oids &&
514 cat >expect <<-EOF &&
515 $HTTPD_URL/bundle-1.bundle
516 $HTTPD_URL/bundle-2.bundle
517 $HTTPD_URL/bundle-3.bundle
518 $HTTPD_URL/bundle-4.bundle
519 $HTTPD_URL/bundle-list
522 # Sort the list, since the order is not well-defined
523 # without a heuristic.
524 test_remote_https_urls <trace-clone.txt | sort >actual &&
525 test_cmp expect actual
528 test_expect_success 'clone bundle list (HTTP, any mode)' '
529 cp clone-from/bundle-*.bundle "$HTTPD_DOCUMENT_ROOT_PATH/" &&
530 cat >"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
531 [bundle]
532 version = 1
533 mode = any
535 # Does not exist. Should be skipped.
536 [bundle "bundle-0"]
537 uri = $HTTPD_URL/bundle-0.bundle
539 [bundle "bundle-1"]
540 uri = $HTTPD_URL/bundle-1.bundle
542 # Does not exist. Should be skipped.
543 [bundle "bundle-5"]
544 uri = $HTTPD_URL/bundle-5.bundle
547 git clone --bundle-uri="$HTTPD_URL/bundle-list" \
548 clone-from clone-any-http 2>err &&
549 ! grep "fatal" err &&
550 grep "warning: failed to download bundle from URI" err &&
552 git -C clone-from for-each-ref --format="%(objectname)" >oids &&
553 git -C clone-any-http cat-file --batch-check <oids &&
555 git -C clone-list-file for-each-ref --format="%(refname)" >refs &&
556 grep "refs/bundles/" refs >actual &&
557 cat >expect <<-\EOF &&
558 refs/bundles/base
559 refs/bundles/left
560 refs/bundles/merge
561 refs/bundles/right
563 test_cmp expect actual
566 test_expect_success 'clone bundle list (http, creationToken)' '
567 test_when_finished rm -f trace*.txt &&
569 cp clone-from/bundle-*.bundle "$HTTPD_DOCUMENT_ROOT_PATH/" &&
570 cat >"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
571 [bundle]
572 version = 1
573 mode = all
574 heuristic = creationToken
576 [bundle "bundle-1"]
577 uri = bundle-1.bundle
578 creationToken = 1
580 [bundle "bundle-2"]
581 uri = bundle-2.bundle
582 creationToken = 2
584 [bundle "bundle-3"]
585 uri = bundle-3.bundle
586 creationToken = 3
588 [bundle "bundle-4"]
589 uri = bundle-4.bundle
590 creationToken = 4
593 GIT_TRACE2_EVENT="$(pwd)/trace-clone.txt" git \
594 clone --bundle-uri="$HTTPD_URL/bundle-list" \
595 "$HTTPD_URL/smart/fetch.git" clone-list-http-2 &&
597 git -C clone-from for-each-ref --format="%(objectname)" >oids &&
598 git -C clone-list-http-2 cat-file --batch-check <oids &&
600 cat >expect <<-EOF &&
601 $HTTPD_URL/bundle-list
602 $HTTPD_URL/bundle-4.bundle
603 $HTTPD_URL/bundle-3.bundle
604 $HTTPD_URL/bundle-2.bundle
605 $HTTPD_URL/bundle-1.bundle
608 test_remote_https_urls <trace-clone.txt >actual &&
609 test_cmp expect actual
612 test_expect_success 'clone incomplete bundle list (http, creationToken)' '
613 test_when_finished rm -f trace*.txt &&
615 cp clone-from/bundle-*.bundle "$HTTPD_DOCUMENT_ROOT_PATH/" &&
616 cat >"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
617 [bundle]
618 version = 1
619 mode = all
620 heuristic = creationToken
622 [bundle "bundle-1"]
623 uri = bundle-1.bundle
624 creationToken = 1
627 GIT_TRACE2_EVENT=$(pwd)/trace-clone.txt \
628 git clone --bundle-uri="$HTTPD_URL/bundle-list" \
629 --single-branch --branch=base --no-tags \
630 "$HTTPD_URL/smart/fetch.git" clone-token-http &&
632 test_cmp_config -C clone-token-http "$HTTPD_URL/bundle-list" fetch.bundleuri &&
633 test_cmp_config -C clone-token-http 1 fetch.bundlecreationtoken &&
635 cat >expect <<-EOF &&
636 $HTTPD_URL/bundle-list
637 $HTTPD_URL/bundle-1.bundle
640 test_remote_https_urls <trace-clone.txt >actual &&
641 test_cmp expect actual &&
643 # We now have only one bundle ref.
644 git -C clone-token-http for-each-ref --format="%(refname)" "refs/bundles/*" >refs &&
645 cat >expect <<-\EOF &&
646 refs/bundles/base
648 test_cmp expect refs &&
650 # Add remaining bundles, exercising the "deepening" strategy
651 # for downloading via the creationToken heurisitc.
652 cat >>"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
653 [bundle "bundle-2"]
654 uri = bundle-2.bundle
655 creationToken = 2
657 [bundle "bundle-3"]
658 uri = bundle-3.bundle
659 creationToken = 3
661 [bundle "bundle-4"]
662 uri = bundle-4.bundle
663 creationToken = 4
666 GIT_TRACE2_EVENT="$(pwd)/trace1.txt" \
667 git -C clone-token-http fetch origin --no-tags \
668 refs/heads/merge:refs/heads/merge &&
669 test_cmp_config -C clone-token-http 4 fetch.bundlecreationtoken &&
671 cat >expect <<-EOF &&
672 $HTTPD_URL/bundle-list
673 $HTTPD_URL/bundle-4.bundle
674 $HTTPD_URL/bundle-3.bundle
675 $HTTPD_URL/bundle-2.bundle
678 test_remote_https_urls <trace1.txt >actual &&
679 test_cmp expect actual &&
681 # We now have all bundle refs.
682 git -C clone-token-http for-each-ref --format="%(refname)" "refs/bundles/*" >refs &&
684 cat >expect <<-\EOF &&
685 refs/bundles/base
686 refs/bundles/left
687 refs/bundles/merge
688 refs/bundles/right
690 test_cmp expect refs
693 test_expect_success 'http clone with bundle.heuristic creates fetch.bundleURI' '
694 test_when_finished rm -rf fetch-http-4 trace*.txt &&
696 cat >"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
697 [bundle]
698 version = 1
699 mode = all
700 heuristic = creationToken
702 [bundle "bundle-1"]
703 uri = bundle-1.bundle
704 creationToken = 1
707 GIT_TRACE2_EVENT="$(pwd)/trace-clone.txt" \
708 git clone --single-branch --branch=base \
709 --bundle-uri="$HTTPD_URL/bundle-list" \
710 "$HTTPD_URL/smart/fetch.git" fetch-http-4 &&
712 test_cmp_config -C fetch-http-4 "$HTTPD_URL/bundle-list" fetch.bundleuri &&
713 test_cmp_config -C fetch-http-4 1 fetch.bundlecreationtoken &&
715 cat >expect <<-EOF &&
716 $HTTPD_URL/bundle-list
717 $HTTPD_URL/bundle-1.bundle
720 test_remote_https_urls <trace-clone.txt >actual &&
721 test_cmp expect actual &&
723 # only received base ref from bundle-1
724 git -C fetch-http-4 for-each-ref --format="%(refname)" "refs/bundles/*" >refs &&
725 cat >expect <<-\EOF &&
726 refs/bundles/base
728 test_cmp expect refs &&
730 cat >>"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
731 [bundle "bundle-2"]
732 uri = bundle-2.bundle
733 creationToken = 2
736 # Fetch the objects for bundle-2 _and_ bundle-3.
737 GIT_TRACE2_EVENT="$(pwd)/trace1.txt" \
738 git -C fetch-http-4 fetch origin --no-tags \
739 refs/heads/left:refs/heads/left \
740 refs/heads/right:refs/heads/right &&
741 test_cmp_config -C fetch-http-4 2 fetch.bundlecreationtoken &&
743 cat >expect <<-EOF &&
744 $HTTPD_URL/bundle-list
745 $HTTPD_URL/bundle-2.bundle
748 test_remote_https_urls <trace1.txt >actual &&
749 test_cmp expect actual &&
751 # received left from bundle-2
752 git -C fetch-http-4 for-each-ref --format="%(refname)" "refs/bundles/*" >refs &&
753 cat >expect <<-\EOF &&
754 refs/bundles/base
755 refs/bundles/left
757 test_cmp expect refs &&
759 # No-op fetch
760 GIT_TRACE2_EVENT="$(pwd)/trace1b.txt" \
761 git -C fetch-http-4 fetch origin --no-tags \
762 refs/heads/left:refs/heads/left \
763 refs/heads/right:refs/heads/right &&
765 cat >expect <<-EOF &&
766 $HTTPD_URL/bundle-list
768 test_remote_https_urls <trace1b.txt >actual &&
769 test_cmp expect actual &&
771 cat >>"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
772 [bundle "bundle-3"]
773 uri = bundle-3.bundle
774 creationToken = 3
776 [bundle "bundle-4"]
777 uri = bundle-4.bundle
778 creationToken = 4
781 # This fetch should skip bundle-3.bundle, since its objects are
782 # already local (we have the requisite commits for bundle-4.bundle).
783 GIT_TRACE2_EVENT="$(pwd)/trace2.txt" \
784 git -C fetch-http-4 fetch origin --no-tags \
785 refs/heads/merge:refs/heads/merge &&
786 test_cmp_config -C fetch-http-4 4 fetch.bundlecreationtoken &&
788 cat >expect <<-EOF &&
789 $HTTPD_URL/bundle-list
790 $HTTPD_URL/bundle-4.bundle
793 test_remote_https_urls <trace2.txt >actual &&
794 test_cmp expect actual &&
796 # received merge ref from bundle-4, but right is missing
797 # because we did not download bundle-3.
798 git -C fetch-http-4 for-each-ref --format="%(refname)" "refs/bundles/*" >refs &&
800 cat >expect <<-\EOF &&
801 refs/bundles/base
802 refs/bundles/left
803 refs/bundles/merge
805 test_cmp expect refs &&
807 # No-op fetch
808 GIT_TRACE2_EVENT="$(pwd)/trace2b.txt" \
809 git -C fetch-http-4 fetch origin &&
811 cat >expect <<-EOF &&
812 $HTTPD_URL/bundle-list
814 test_remote_https_urls <trace2b.txt >actual &&
815 test_cmp expect actual
818 test_expect_success 'creationToken heuristic with failed downloads (clone)' '
819 test_when_finished rm -rf download-* trace*.txt &&
821 # Case 1: base bundle does not exist, nothing can unbundle
822 cat >"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
823 [bundle]
824 version = 1
825 mode = all
826 heuristic = creationToken
828 [bundle "bundle-1"]
829 uri = fake.bundle
830 creationToken = 1
832 [bundle "bundle-2"]
833 uri = bundle-2.bundle
834 creationToken = 2
836 [bundle "bundle-3"]
837 uri = bundle-3.bundle
838 creationToken = 3
840 [bundle "bundle-4"]
841 uri = bundle-4.bundle
842 creationToken = 4
845 GIT_TRACE2_EVENT="$(pwd)/trace-clone-1.txt" \
846 git clone --single-branch --branch=base \
847 --bundle-uri="$HTTPD_URL/bundle-list" \
848 "$HTTPD_URL/smart/fetch.git" download-1 &&
850 # Bundle failure does not set these configs.
851 test_must_fail git -C download-1 config fetch.bundleuri &&
852 test_must_fail git -C download-1 config fetch.bundlecreationtoken &&
854 cat >expect <<-EOF &&
855 $HTTPD_URL/bundle-list
856 $HTTPD_URL/bundle-4.bundle
857 $HTTPD_URL/bundle-3.bundle
858 $HTTPD_URL/bundle-2.bundle
859 $HTTPD_URL/fake.bundle
861 test_remote_https_urls <trace-clone-1.txt >actual &&
862 test_cmp expect actual &&
864 # All bundles failed to unbundle
865 git -C download-1 for-each-ref --format="%(refname)" "refs/bundles/*" >refs &&
866 test_must_be_empty refs &&
868 # Case 2: middle bundle does not exist, only two bundles can unbundle
869 cat >"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
870 [bundle]
871 version = 1
872 mode = all
873 heuristic = creationToken
875 [bundle "bundle-1"]
876 uri = bundle-1.bundle
877 creationToken = 1
879 [bundle "bundle-2"]
880 uri = fake.bundle
881 creationToken = 2
883 [bundle "bundle-3"]
884 uri = bundle-3.bundle
885 creationToken = 3
887 [bundle "bundle-4"]
888 uri = bundle-4.bundle
889 creationToken = 4
892 GIT_TRACE2_EVENT="$(pwd)/trace-clone-2.txt" \
893 git clone --single-branch --branch=base \
894 --bundle-uri="$HTTPD_URL/bundle-list" \
895 "$HTTPD_URL/smart/fetch.git" download-2 &&
897 # Bundle failure does not set these configs.
898 test_must_fail git -C download-2 config fetch.bundleuri &&
899 test_must_fail git -C download-2 config fetch.bundlecreationtoken &&
901 cat >expect <<-EOF &&
902 $HTTPD_URL/bundle-list
903 $HTTPD_URL/bundle-4.bundle
904 $HTTPD_URL/bundle-3.bundle
905 $HTTPD_URL/fake.bundle
906 $HTTPD_URL/bundle-1.bundle
908 test_remote_https_urls <trace-clone-2.txt >actual &&
909 test_cmp expect actual &&
911 # bundle-1 and bundle-3 could unbundle, but bundle-4 could not
912 git -C download-2 for-each-ref --format="%(refname)" "refs/bundles/*" >refs &&
913 cat >expect <<-EOF &&
914 refs/bundles/base
915 refs/bundles/right
917 test_cmp expect refs &&
919 # Case 3: top bundle does not exist, rest unbundle fine.
920 cat >"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
921 [bundle]
922 version = 1
923 mode = all
924 heuristic = creationToken
926 [bundle "bundle-1"]
927 uri = bundle-1.bundle
928 creationToken = 1
930 [bundle "bundle-2"]
931 uri = bundle-2.bundle
932 creationToken = 2
934 [bundle "bundle-3"]
935 uri = bundle-3.bundle
936 creationToken = 3
938 [bundle "bundle-4"]
939 uri = fake.bundle
940 creationToken = 4
943 GIT_TRACE2_EVENT="$(pwd)/trace-clone-3.txt" \
944 git clone --single-branch --branch=base \
945 --bundle-uri="$HTTPD_URL/bundle-list" \
946 "$HTTPD_URL/smart/fetch.git" download-3 &&
948 # As long as we have continguous successful downloads,
949 # we _do_ set these configs.
950 test_cmp_config -C download-3 "$HTTPD_URL/bundle-list" fetch.bundleuri &&
951 test_cmp_config -C download-3 3 fetch.bundlecreationtoken &&
953 cat >expect <<-EOF &&
954 $HTTPD_URL/bundle-list
955 $HTTPD_URL/fake.bundle
956 $HTTPD_URL/bundle-3.bundle
957 $HTTPD_URL/bundle-2.bundle
958 $HTTPD_URL/bundle-1.bundle
960 test_remote_https_urls <trace-clone-3.txt >actual &&
961 test_cmp expect actual &&
963 # fake.bundle did not unbundle, but the others did.
964 git -C download-3 for-each-ref --format="%(refname)" "refs/bundles/*" >refs &&
965 cat >expect <<-EOF &&
966 refs/bundles/base
967 refs/bundles/left
968 refs/bundles/right
970 test_cmp expect refs
973 # Expand the bundle list to include other interesting shapes, specifically
974 # interesting for use when fetching from a previous state.
976 # ---------------- bundle-7
978 # _/|\_
979 # ---/--|--\------ bundle-6
980 # 5 | 6
981 # --|---|---|----- bundle-4
982 # | 4 |
983 # | / \ /
984 # --|-|---|/------ bundle-3 (the client will be caught up to this point.)
985 # \ | 3
986 # ---\|---|------- bundle-2
987 # 2 |
988 # ----|---|------- bundle-1
989 # \ /
992 # (previous commits)
993 test_expect_success 'expand incremental bundle list' '
995 cd clone-from &&
996 git checkout -b lefter left &&
997 test_commit 5 &&
998 git checkout -b righter right &&
999 test_commit 6 &&
1000 git checkout -b top lefter &&
1001 git merge -m "7" merge righter &&
1003 git bundle create bundle-6.bundle lefter righter --not left right &&
1004 git bundle create bundle-7.bundle top --not lefter merge righter &&
1006 cp bundle-*.bundle "$HTTPD_DOCUMENT_ROOT_PATH/"
1007 ) &&
1008 git -C "$HTTPD_DOCUMENT_ROOT_PATH/fetch.git" fetch origin +refs/heads/*:refs/heads/*
1011 test_expect_success 'creationToken heuristic with failed downloads (fetch)' '
1012 test_when_finished rm -rf download-* trace*.txt &&
1014 cat >"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
1015 [bundle]
1016 version = 1
1017 mode = all
1018 heuristic = creationToken
1020 [bundle "bundle-1"]
1021 uri = bundle-1.bundle
1022 creationToken = 1
1024 [bundle "bundle-2"]
1025 uri = bundle-2.bundle
1026 creationToken = 2
1028 [bundle "bundle-3"]
1029 uri = bundle-3.bundle
1030 creationToken = 3
1033 git clone --single-branch --branch=left \
1034 --bundle-uri="$HTTPD_URL/bundle-list" \
1035 "$HTTPD_URL/smart/fetch.git" fetch-base &&
1036 test_cmp_config -C fetch-base "$HTTPD_URL/bundle-list" fetch.bundleURI &&
1037 test_cmp_config -C fetch-base 3 fetch.bundleCreationToken &&
1039 # Case 1: all bundles exist: successful unbundling of all bundles
1040 cat >"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
1041 [bundle]
1042 version = 1
1043 mode = all
1044 heuristic = creationToken
1046 [bundle "bundle-1"]
1047 uri = bundle-1.bundle
1048 creationToken = 1
1050 [bundle "bundle-2"]
1051 uri = bundle-2.bundle
1052 creationToken = 2
1054 [bundle "bundle-3"]
1055 uri = bundle-3.bundle
1056 creationToken = 3
1058 [bundle "bundle-4"]
1059 uri = bundle-4.bundle
1060 creationToken = 4
1062 [bundle "bundle-6"]
1063 uri = bundle-6.bundle
1064 creationToken = 6
1066 [bundle "bundle-7"]
1067 uri = bundle-7.bundle
1068 creationToken = 7
1071 cp -r fetch-base fetch-1 &&
1072 GIT_TRACE2_EVENT="$(pwd)/trace-fetch-1.txt" \
1073 git -C fetch-1 fetch origin &&
1074 test_cmp_config -C fetch-1 7 fetch.bundlecreationtoken &&
1076 cat >expect <<-EOF &&
1077 $HTTPD_URL/bundle-list
1078 $HTTPD_URL/bundle-7.bundle
1079 $HTTPD_URL/bundle-6.bundle
1080 $HTTPD_URL/bundle-4.bundle
1082 test_remote_https_urls <trace-fetch-1.txt >actual &&
1083 test_cmp expect actual &&
1085 # Check which bundles have unbundled by refs
1086 git -C fetch-1 for-each-ref --format="%(refname)" "refs/bundles/*" >refs &&
1087 cat >expect <<-EOF &&
1088 refs/bundles/base
1089 refs/bundles/left
1090 refs/bundles/lefter
1091 refs/bundles/merge
1092 refs/bundles/right
1093 refs/bundles/righter
1094 refs/bundles/top
1096 test_cmp expect refs &&
1098 # Case 2: middle bundle does not exist, only bundle-4 can unbundle
1099 cat >"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
1100 [bundle]
1101 version = 1
1102 mode = all
1103 heuristic = creationToken
1105 [bundle "bundle-1"]
1106 uri = bundle-1.bundle
1107 creationToken = 1
1109 [bundle "bundle-2"]
1110 uri = bundle-2.bundle
1111 creationToken = 2
1113 [bundle "bundle-3"]
1114 uri = bundle-3.bundle
1115 creationToken = 3
1117 [bundle "bundle-4"]
1118 uri = bundle-4.bundle
1119 creationToken = 4
1121 [bundle "bundle-6"]
1122 uri = fake.bundle
1123 creationToken = 6
1125 [bundle "bundle-7"]
1126 uri = bundle-7.bundle
1127 creationToken = 7
1130 cp -r fetch-base fetch-2 &&
1131 GIT_TRACE2_EVENT="$(pwd)/trace-fetch-2.txt" \
1132 git -C fetch-2 fetch origin &&
1134 # Since bundle-7 fails to unbundle, do not update creation token.
1135 test_cmp_config -C fetch-2 3 fetch.bundlecreationtoken &&
1137 cat >expect <<-EOF &&
1138 $HTTPD_URL/bundle-list
1139 $HTTPD_URL/bundle-7.bundle
1140 $HTTPD_URL/fake.bundle
1141 $HTTPD_URL/bundle-4.bundle
1143 test_remote_https_urls <trace-fetch-2.txt >actual &&
1144 test_cmp expect actual &&
1146 # Check which bundles have unbundled by refs
1147 git -C fetch-2 for-each-ref --format="%(refname)" "refs/bundles/*" >refs &&
1148 cat >expect <<-EOF &&
1149 refs/bundles/base
1150 refs/bundles/left
1151 refs/bundles/merge
1152 refs/bundles/right
1154 test_cmp expect refs &&
1156 # Case 3: top bundle does not exist, rest unbundle fine.
1157 cat >"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
1158 [bundle]
1159 version = 1
1160 mode = all
1161 heuristic = creationToken
1163 [bundle "bundle-1"]
1164 uri = bundle-1.bundle
1165 creationToken = 1
1167 [bundle "bundle-2"]
1168 uri = bundle-2.bundle
1169 creationToken = 2
1171 [bundle "bundle-3"]
1172 uri = bundle-3.bundle
1173 creationToken = 3
1175 [bundle "bundle-4"]
1176 uri = bundle-4.bundle
1177 creationToken = 4
1179 [bundle "bundle-6"]
1180 uri = bundle-6.bundle
1181 creationToken = 6
1183 [bundle "bundle-7"]
1184 uri = fake.bundle
1185 creationToken = 7
1188 cp -r fetch-base fetch-3 &&
1189 GIT_TRACE2_EVENT="$(pwd)/trace-fetch-3.txt" \
1190 git -C fetch-3 fetch origin &&
1192 # As long as we have continguous successful downloads,
1193 # we _do_ set the maximum creation token.
1194 test_cmp_config -C fetch-3 6 fetch.bundlecreationtoken &&
1196 # NOTE: the fetch skips bundle-4 since bundle-6 successfully
1197 # unbundles itself and bundle-7 failed to download.
1198 cat >expect <<-EOF &&
1199 $HTTPD_URL/bundle-list
1200 $HTTPD_URL/fake.bundle
1201 $HTTPD_URL/bundle-6.bundle
1203 test_remote_https_urls <trace-fetch-3.txt >actual &&
1204 test_cmp expect actual &&
1206 # Check which bundles have unbundled by refs
1207 git -C fetch-3 for-each-ref --format="%(refname)" "refs/bundles/*" >refs &&
1208 cat >expect <<-EOF &&
1209 refs/bundles/base
1210 refs/bundles/left
1211 refs/bundles/lefter
1212 refs/bundles/right
1213 refs/bundles/righter
1215 test_cmp expect refs
1218 test_expect_success 'bundles are downloaded once during fetch --all' '
1219 test_when_finished rm -rf download-* trace*.txt fetch-mult &&
1221 cat >"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
1222 [bundle]
1223 version = 1
1224 mode = all
1225 heuristic = creationToken
1227 [bundle "bundle-1"]
1228 uri = bundle-1.bundle
1229 creationToken = 1
1231 [bundle "bundle-2"]
1232 uri = bundle-2.bundle
1233 creationToken = 2
1235 [bundle "bundle-3"]
1236 uri = bundle-3.bundle
1237 creationToken = 3
1240 git clone --single-branch --branch=left \
1241 --bundle-uri="$HTTPD_URL/bundle-list" \
1242 "$HTTPD_URL/smart/fetch.git" fetch-mult &&
1243 git -C fetch-mult remote add dup1 "$HTTPD_URL/smart/fetch.git" &&
1244 git -C fetch-mult remote add dup2 "$HTTPD_URL/smart/fetch.git" &&
1246 GIT_TRACE2_EVENT="$(pwd)/trace-mult.txt" \
1247 git -C fetch-mult fetch --all &&
1248 grep "\"child_start\".*\"git-remote-https\",\"$HTTPD_URL/bundle-list\"" \
1249 trace-mult.txt >bundle-fetches &&
1250 test_line_count = 1 bundle-fetches
1252 # Do not add tests here unless they use the HTTP server, as they will
1253 # not run unless the HTTP dependencies exist.
1255 test_done