Git fork
1#!/bin/sh
2#
3# Copyright (c) 2021 Jiang Xin
4#
5
6test_description='Test git-bundle'
7
8GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
9export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
10
11. ./test-lib.sh
12. "$TEST_DIRECTORY"/lib-bundle.sh
13. "$TEST_DIRECTORY"/lib-terminal.sh
14
15for cmd in create verify list-heads unbundle
16do
17 test_expect_success "usage: git bundle $cmd needs an argument" '
18 test_expect_code 129 git bundle $cmd
19 '
20done
21
22# Create a commit or tag and set the variable with the object ID.
23test_commit_setvar () {
24 notick=
25 signoff=
26 indir=
27 merge=
28 tag=
29 var=
30
31 while test $# != 0
32 do
33 case "$1" in
34 --merge)
35 merge=t
36 ;;
37 --tag)
38 tag=t
39 ;;
40 --notick)
41 notick=t
42 ;;
43 --signoff)
44 signoff="$1"
45 ;;
46 -C)
47 shift
48 indir="$1"
49 ;;
50 -*)
51 echo >&2 "error: unknown option $1"
52 return 1
53 ;;
54 *)
55 break
56 ;;
57 esac
58 shift
59 done
60 if test $# -lt 2
61 then
62 echo >&2 "error: test_commit_setvar must have at least 2 arguments"
63 return 1
64 fi
65 var=$1
66 shift
67 indir=${indir:+"$indir"/}
68 if test -z "$notick"
69 then
70 test_tick
71 fi &&
72 if test -n "$merge"
73 then
74 git ${indir:+ -C "$indir"} merge --no-edit --no-ff \
75 ${2:+-m "$2"} "$1" &&
76 oid=$(git ${indir:+ -C "$indir"} rev-parse HEAD)
77 elif test -n "$tag"
78 then
79 git ${indir:+ -C "$indir"} tag -m "$1" "$1" "${2:-HEAD}" &&
80 oid=$(git ${indir:+ -C "$indir"} rev-parse "$1")
81 else
82 file=${2:-"$1.t"} &&
83 echo "${3-$1}" >"$indir$file" &&
84 git ${indir:+ -C "$indir"} add "$file" &&
85 git ${indir:+ -C "$indir"} commit $signoff -m "$1" &&
86 oid=$(git ${indir:+ -C "$indir"} rev-parse HEAD)
87 fi &&
88 eval $var=$oid
89}
90
91get_abbrev_oid () {
92 oid=$1 &&
93 suffix=${oid#???????} &&
94 oid=${oid%$suffix} &&
95 if test -n "$oid"
96 then
97 echo "$oid"
98 else
99 echo "undefined-oid"
100 fi
101}
102
103# Format the output of git commands to make a user-friendly and stable
104# text. We can easily prepare the expect text without having to worry
105# about future changes of the commit ID.
106make_user_friendly_and_stable_output () {
107 sed \
108 -e "s/$(get_abbrev_oid $A)[0-9a-f]*/<COMMIT-A>/g" \
109 -e "s/$(get_abbrev_oid $B)[0-9a-f]*/<COMMIT-B>/g" \
110 -e "s/$(get_abbrev_oid $C)[0-9a-f]*/<COMMIT-C>/g" \
111 -e "s/$(get_abbrev_oid $D)[0-9a-f]*/<COMMIT-D>/g" \
112 -e "s/$(get_abbrev_oid $E)[0-9a-f]*/<COMMIT-E>/g" \
113 -e "s/$(get_abbrev_oid $F)[0-9a-f]*/<COMMIT-F>/g" \
114 -e "s/$(get_abbrev_oid $G)[0-9a-f]*/<COMMIT-G>/g" \
115 -e "s/$(get_abbrev_oid $H)[0-9a-f]*/<COMMIT-H>/g" \
116 -e "s/$(get_abbrev_oid $I)[0-9a-f]*/<COMMIT-I>/g" \
117 -e "s/$(get_abbrev_oid $J)[0-9a-f]*/<COMMIT-J>/g" \
118 -e "s/$(get_abbrev_oid $K)[0-9a-f]*/<COMMIT-K>/g" \
119 -e "s/$(get_abbrev_oid $L)[0-9a-f]*/<COMMIT-L>/g" \
120 -e "s/$(get_abbrev_oid $M)[0-9a-f]*/<COMMIT-M>/g" \
121 -e "s/$(get_abbrev_oid $N)[0-9a-f]*/<COMMIT-N>/g" \
122 -e "s/$(get_abbrev_oid $O)[0-9a-f]*/<COMMIT-O>/g" \
123 -e "s/$(get_abbrev_oid $P)[0-9a-f]*/<COMMIT-P>/g" \
124 -e "s/$(get_abbrev_oid $TAG1)[0-9a-f]*/<TAG-1>/g" \
125 -e "s/$(get_abbrev_oid $TAG2)[0-9a-f]*/<TAG-2>/g" \
126 -e "s/$(get_abbrev_oid $TAG3)[0-9a-f]*/<TAG-3>/g"
127}
128
129format_and_save_expect () {
130 sed -e 's/Z$//' >expect
131}
132
133HASH_MESSAGE="The bundle uses this hash algorithm: $GIT_DEFAULT_HASH"
134
135# (C) (D, pull/1/head, topic/1)
136# o --- o
137# / \ (L)
138# / \ o (H, topic/2) (M, tag:v2)
139# / (F) \ / (N, tag:v3)
140# / o --------- o (G, pull/2/head) o --- o --- o (release)
141# / / \ \ / \
142# o --- o --- o -------- o -- o ------------------ o ------- o --- o (main)
143# (A) (B) (E, tag:v1) (I) (J) (K) (O) (P)
144#
145test_expect_success 'setup' '
146 # Try to make a stable fixed width for abbreviated commit ID,
147 # this fixed-width oid will be replaced with "<OID>".
148 git config core.abbrev 7 &&
149
150 # branch main: commit A & B
151 test_commit_setvar A "Commit A" main.txt &&
152 test_commit_setvar B "Commit B" main.txt &&
153
154 # branch topic/1: commit C & D, refs/pull/1/head
155 git checkout -b topic/1 &&
156 test_commit_setvar C "Commit C" topic-1.txt &&
157 test_commit_setvar D "Commit D" topic-1.txt &&
158 git update-ref refs/pull/1/head HEAD &&
159
160 # branch topic/1: commit E, tag v1
161 git checkout main &&
162 test_commit_setvar E "Commit E" main.txt &&
163 test_commit_setvar --tag TAG1 v1 &&
164
165 # branch topic/2: commit F & G, refs/pull/2/head
166 git checkout -b topic/2 &&
167 test_commit_setvar F "Commit F" topic-2.txt &&
168 test_commit_setvar G "Commit G" topic-2.txt &&
169 git update-ref refs/pull/2/head HEAD &&
170 test_commit_setvar H "Commit H" topic-2.txt &&
171
172 # branch main: merge commit I & J
173 git checkout main &&
174 test_commit_setvar --merge I topic/1 "Merge commit I" &&
175 test_commit_setvar --merge J refs/pull/2/head "Merge commit J" &&
176
177 # branch main: commit K
178 git checkout main &&
179 test_commit_setvar K "Commit K" main.txt &&
180
181 # branch release:
182 git checkout -b release &&
183 test_commit_setvar L "Commit L" release.txt &&
184 test_commit_setvar M "Commit M" release.txt &&
185 test_commit_setvar --tag TAG2 v2 &&
186 test_commit_setvar N "Commit N" release.txt &&
187 test_commit_setvar --tag TAG3 v3 &&
188
189 # branch main: merge commit O, commit P
190 git checkout main &&
191 test_commit_setvar --merge O tags/v2 "Merge commit O" &&
192 test_commit_setvar P "Commit P" main.txt
193'
194
195test_expect_success 'create bundle from special rev: main^!' '
196 git bundle create special-rev.bdl "main^!" &&
197
198 git bundle list-heads special-rev.bdl |
199 make_user_friendly_and_stable_output >actual &&
200 cat >expect <<-\EOF &&
201 <COMMIT-P> refs/heads/main
202 EOF
203 test_cmp expect actual &&
204
205 git bundle verify special-rev.bdl |
206 make_user_friendly_and_stable_output >actual &&
207 format_and_save_expect <<-EOF &&
208 The bundle contains this ref:
209 <COMMIT-P> refs/heads/main
210 The bundle requires this ref:
211 <COMMIT-O> Z
212 $HASH_MESSAGE
213 EOF
214 test_cmp expect actual &&
215
216 test_bundle_object_count special-rev.bdl 3
217'
218
219test_expect_success 'create bundle with --max-count option' '
220 git bundle create max-count.bdl --max-count 1 \
221 main \
222 "^release" \
223 refs/tags/v1 \
224 refs/pull/1/head \
225 refs/pull/2/head &&
226
227 git bundle verify max-count.bdl |
228 make_user_friendly_and_stable_output >actual &&
229 format_and_save_expect <<-EOF &&
230 The bundle contains these 2 refs:
231 <COMMIT-P> refs/heads/main
232 <TAG-1> refs/tags/v1
233 The bundle requires this ref:
234 <COMMIT-O> Z
235 $HASH_MESSAGE
236 EOF
237 test_cmp expect actual &&
238
239 test_bundle_object_count max-count.bdl 4
240'
241
242test_expect_success 'create bundle with --since option' '
243 git log -1 --pretty="%ad" $M >actual &&
244 cat >expect <<-\EOF &&
245 Thu Apr 7 15:26:13 2005 -0700
246 EOF
247 test_cmp expect actual &&
248
249 # If a different name hash function is used, then one fewer
250 # delta base is found and this counts a different number
251 # of objects after performing --fix-thin.
252 GIT_TEST_NAME_HASH_VERSION=1 \
253 git bundle create since.bdl \
254 --since "Thu Apr 7 15:27:00 2005 -0700" \
255 --all &&
256
257 git bundle verify since.bdl |
258 make_user_friendly_and_stable_output >actual &&
259 format_and_save_expect <<-EOF &&
260 The bundle contains these 5 refs:
261 <COMMIT-P> refs/heads/main
262 <COMMIT-N> refs/heads/release
263 <TAG-2> refs/tags/v2
264 <TAG-3> refs/tags/v3
265 <COMMIT-P> HEAD
266 The bundle requires these 2 refs:
267 <COMMIT-M> Z
268 <COMMIT-K> Z
269 $HASH_MESSAGE
270 EOF
271 test_cmp expect actual &&
272
273 test_bundle_object_count --thin since.bdl 13
274'
275
276test_expect_success 'create bundle 1 - no prerequisites' '
277 # create bundle from args
278 git bundle create 1.bdl topic/1 topic/2 &&
279
280 # create bundle from stdin
281 cat >input <<-\EOF &&
282 topic/1
283 topic/2
284 EOF
285 git bundle create stdin-1.bdl --stdin <input &&
286
287 format_and_save_expect <<-EOF &&
288 The bundle contains these 2 refs:
289 <COMMIT-D> refs/heads/topic/1
290 <COMMIT-H> refs/heads/topic/2
291 The bundle records a complete history.
292 $HASH_MESSAGE
293 EOF
294
295 # verify bundle, which has no prerequisites
296 git bundle verify 1.bdl |
297 make_user_friendly_and_stable_output >actual &&
298 test_cmp expect actual &&
299
300 git bundle verify stdin-1.bdl |
301 make_user_friendly_and_stable_output >actual &&
302 test_cmp expect actual &&
303
304 test_bundle_object_count 1.bdl 24 &&
305 test_bundle_object_count stdin-1.bdl 24
306'
307
308test_expect_success 'create bundle 2 - has prerequisites' '
309 # create bundle from args
310 git bundle create 2.bdl \
311 --ignore-missing \
312 ^topic/deleted \
313 ^$D \
314 ^topic/2 \
315 release &&
316
317 # create bundle from stdin
318 # input has a non-exist reference: "topic/deleted"
319 cat >input <<-EOF &&
320 ^topic/deleted
321 ^$D
322 ^topic/2
323 EOF
324 git bundle create stdin-2.bdl \
325 --ignore-missing \
326 --stdin \
327 release <input &&
328
329 format_and_save_expect <<-EOF &&
330 The bundle contains this ref:
331 <COMMIT-N> refs/heads/release
332 The bundle requires these 3 refs:
333 <COMMIT-D> Z
334 <COMMIT-E> Z
335 <COMMIT-G> Z
336 $HASH_MESSAGE
337 EOF
338
339 git bundle verify 2.bdl |
340 make_user_friendly_and_stable_output >actual &&
341 test_cmp expect actual &&
342
343 git bundle verify stdin-2.bdl |
344 make_user_friendly_and_stable_output >actual &&
345 test_cmp expect actual &&
346
347 test_bundle_object_count 2.bdl 16 &&
348 test_bundle_object_count stdin-2.bdl 16
349'
350
351test_expect_success 'fail to verify bundle without prerequisites' '
352 git init --bare test1.git &&
353
354 format_and_save_expect <<-\EOF &&
355 error: Repository lacks these prerequisite commits:
356 error: <COMMIT-D> Z
357 error: <COMMIT-E> Z
358 error: <COMMIT-G> Z
359 EOF
360
361 test_must_fail git -C test1.git bundle verify ../2.bdl 2>&1 |
362 make_user_friendly_and_stable_output >actual &&
363 test_cmp expect actual &&
364
365 test_must_fail git -C test1.git bundle verify ../stdin-2.bdl 2>&1 |
366 make_user_friendly_and_stable_output >actual &&
367 test_cmp expect actual
368'
369
370test_expect_success 'create bundle 3 - two refs, same object' '
371 # create bundle from args
372 git bundle create --version=3 3.bdl \
373 ^release \
374 ^topic/1 \
375 ^topic/2 \
376 main \
377 HEAD &&
378
379 # create bundle from stdin
380 cat >input <<-\EOF &&
381 ^release
382 ^topic/1
383 ^topic/2
384 EOF
385 git bundle create --version=3 stdin-3.bdl \
386 --stdin \
387 main HEAD <input &&
388
389 format_and_save_expect <<-EOF &&
390 The bundle contains these 2 refs:
391 <COMMIT-P> refs/heads/main
392 <COMMIT-P> HEAD
393 The bundle requires these 2 refs:
394 <COMMIT-M> Z
395 <COMMIT-K> Z
396 $HASH_MESSAGE
397 EOF
398
399 git bundle verify 3.bdl |
400 make_user_friendly_and_stable_output >actual &&
401 test_cmp expect actual &&
402
403 git bundle verify stdin-3.bdl |
404 make_user_friendly_and_stable_output >actual &&
405 test_cmp expect actual &&
406
407 test_bundle_object_count 3.bdl 4 &&
408 test_bundle_object_count stdin-3.bdl 4
409'
410
411test_expect_success 'create bundle 4 - with tags' '
412 # create bundle from args
413 git bundle create 4.bdl \
414 ^main \
415 ^release \
416 ^topic/1 \
417 ^topic/2 \
418 --all &&
419
420 # create bundle from stdin
421 cat >input <<-\EOF &&
422 ^main
423 ^release
424 ^topic/1
425 ^topic/2
426 EOF
427 git bundle create stdin-4.bdl \
428 --ignore-missing \
429 --stdin \
430 --all <input &&
431
432 cat >expect <<-EOF &&
433 The bundle contains these 3 refs:
434 <TAG-1> refs/tags/v1
435 <TAG-2> refs/tags/v2
436 <TAG-3> refs/tags/v3
437 The bundle records a complete history.
438 $HASH_MESSAGE
439 EOF
440
441 git bundle verify 4.bdl |
442 make_user_friendly_and_stable_output >actual &&
443 test_cmp expect actual &&
444
445 git bundle verify stdin-4.bdl |
446 make_user_friendly_and_stable_output >actual &&
447 test_cmp expect actual &&
448
449 test_bundle_object_count 4.bdl 3 &&
450 test_bundle_object_count stdin-4.bdl 3
451'
452
453test_expect_success 'clone from bundle' '
454 git clone --mirror 1.bdl mirror.git &&
455 git -C mirror.git show-ref |
456 make_user_friendly_and_stable_output >actual &&
457 cat >expect <<-\EOF &&
458 <COMMIT-D> refs/heads/topic/1
459 <COMMIT-H> refs/heads/topic/2
460 EOF
461 test_cmp expect actual &&
462
463 git -C mirror.git fetch ../2.bdl "+refs/*:refs/*" &&
464 git -C mirror.git show-ref |
465 make_user_friendly_and_stable_output >actual &&
466 cat >expect <<-\EOF &&
467 <COMMIT-N> refs/heads/release
468 <COMMIT-D> refs/heads/topic/1
469 <COMMIT-H> refs/heads/topic/2
470 EOF
471 test_cmp expect actual &&
472
473 git -C mirror.git fetch ../3.bdl "+refs/*:refs/*" &&
474 git -C mirror.git show-ref |
475 make_user_friendly_and_stable_output >actual &&
476 cat >expect <<-\EOF &&
477 <COMMIT-P> refs/heads/main
478 <COMMIT-N> refs/heads/release
479 <COMMIT-D> refs/heads/topic/1
480 <COMMIT-H> refs/heads/topic/2
481 EOF
482 test_cmp expect actual &&
483
484 git -C mirror.git fetch ../4.bdl "+refs/*:refs/*" &&
485 git -C mirror.git show-ref |
486 make_user_friendly_and_stable_output >actual &&
487 cat >expect <<-\EOF &&
488 <COMMIT-P> refs/heads/main
489 <COMMIT-N> refs/heads/release
490 <COMMIT-D> refs/heads/topic/1
491 <COMMIT-H> refs/heads/topic/2
492 <TAG-1> refs/tags/v1
493 <TAG-2> refs/tags/v2
494 <TAG-3> refs/tags/v3
495 EOF
496 test_cmp expect actual
497'
498
499test_expect_success 'unfiltered bundle with --objects' '
500 git bundle create all-objects.bdl \
501 --all --objects &&
502 git bundle create all.bdl \
503 --all &&
504
505 # Compare the headers of these files.
506 sed -n -e "/^$/q" -e "p" all.bdl >expect &&
507 sed -n -e "/^$/q" -e "p" all-objects.bdl >actual &&
508 test_cmp expect actual
509'
510
511test_expect_success 'full bundle upto annotated tag' '
512 git bundle create v2.bdl \
513 v2 &&
514
515 git bundle verify v2.bdl |
516 make_user_friendly_and_stable_output >actual &&
517
518 format_and_save_expect <<-EOF &&
519 The bundle contains this ref:
520 <TAG-2> refs/tags/v2
521 The bundle records a complete history.
522 $HASH_MESSAGE
523 EOF
524 test_cmp expect actual
525'
526
527test_expect_success 'clone from full bundle upto annotated tag' '
528 git clone --mirror v2.bdl tag-clone.git &&
529 git -C tag-clone.git show-ref |
530 make_user_friendly_and_stable_output >actual &&
531 cat >expect <<-\EOF &&
532 <TAG-2> refs/tags/v2
533 EOF
534 test_cmp expect actual
535'
536
537test_expect_success 'incremental bundle between two annotated tags' '
538 git bundle create v1-v2.bdl \
539 v1..v2 &&
540
541 git bundle verify v1-v2.bdl |
542 make_user_friendly_and_stable_output >actual &&
543
544 format_and_save_expect <<-EOF &&
545 The bundle contains this ref:
546 <TAG-2> refs/tags/v2
547 The bundle requires these 2 refs:
548 <COMMIT-E> Z
549 <COMMIT-B> Z
550 $HASH_MESSAGE
551 EOF
552 test_cmp expect actual
553'
554
555for filter in "blob:none" "tree:0" "tree:1" "blob:limit=100"
556do
557 test_expect_success "filtered bundle: $filter" '
558 test_when_finished rm -rf .git/objects/pack cloned unbundled &&
559 git bundle create partial.bdl \
560 --all \
561 --filter=$filter &&
562
563 git bundle verify partial.bdl >unfiltered &&
564 make_user_friendly_and_stable_output <unfiltered >actual &&
565
566 cat >expect <<-EOF &&
567 The bundle contains these 10 refs:
568 <COMMIT-P> refs/heads/main
569 <COMMIT-N> refs/heads/release
570 <COMMIT-D> refs/heads/topic/1
571 <COMMIT-H> refs/heads/topic/2
572 <COMMIT-D> refs/pull/1/head
573 <COMMIT-G> refs/pull/2/head
574 <TAG-1> refs/tags/v1
575 <TAG-2> refs/tags/v2
576 <TAG-3> refs/tags/v3
577 <COMMIT-P> HEAD
578 The bundle records a complete history.
579 $HASH_MESSAGE
580 The bundle uses this filter: $filter
581 EOF
582 test_cmp expect actual &&
583
584 test_config uploadpack.allowfilter 1 &&
585 test_config uploadpack.allowanysha1inwant 1 &&
586 git clone --no-local --filter=$filter --bare "file://$(pwd)" cloned &&
587
588 git init unbundled &&
589 git -C unbundled bundle unbundle ../partial.bdl >ref-list.txt &&
590 ls unbundled/.git/objects/pack/pack-*.promisor >promisor &&
591 test_line_count = 1 promisor &&
592
593 # Count the same number of reachable objects.
594 reflist=$(git for-each-ref --format="%(objectname)") &&
595 git rev-list --objects --filter=$filter --missing=allow-any \
596 $reflist >expect &&
597 for repo in cloned unbundled
598 do
599 git -C $repo rev-list --objects --missing=allow-any \
600 $reflist >actual &&
601 test_cmp expect actual || return 1
602 done
603 '
604done
605
606# NEEDSWORK: 'git clone --bare' should be able to clone from a filtered
607# bundle, but that requires a change to promisor/filter config options.
608# For now, we fail gracefully with a helpful error. This behavior can be
609# changed in the future to succeed as much as possible.
610test_expect_success 'cloning from filtered bundle has useful error' '
611 git bundle create partial.bdl \
612 --all \
613 --filter=blob:none &&
614 test_must_fail git clone --bare partial.bdl partial 2>err &&
615 grep "cannot clone from filtered bundle" err
616'
617
618test_expect_success 'verify catches unreachable, broken prerequisites' '
619 test_when_finished rm -rf clone-from clone-to &&
620 git init clone-from &&
621 (
622 cd clone-from &&
623 git checkout -b base &&
624 test_commit A &&
625 git checkout -b tip &&
626 git commit --allow-empty -m "will drop by shallow" &&
627 git commit --allow-empty -m "will keep by shallow" &&
628 git commit --allow-empty -m "for bundle, not clone" &&
629 git bundle create tip.bundle tip~1..tip &&
630 git reset --hard HEAD~1 &&
631 git checkout base
632 ) &&
633 BAD_OID=$(git -C clone-from rev-parse tip~1) &&
634 TIP_OID=$(git -C clone-from rev-parse tip) &&
635 git clone --depth=1 --no-single-branch \
636 "file://$(pwd)/clone-from" clone-to &&
637 (
638 cd clone-to &&
639
640 # Set up broken history by removing shallow markers
641 git update-ref -d refs/remotes/origin/tip &&
642 rm .git/shallow &&
643
644 # Verify should fail
645 test_must_fail git bundle verify \
646 ../clone-from/tip.bundle 2>err &&
647 grep "some prerequisite commits .* are not connected" err &&
648 test_line_count = 1 err &&
649
650 # Unbundling should fail
651 test_must_fail git bundle unbundle \
652 ../clone-from/tip.bundle 2>err &&
653 grep "some prerequisite commits .* are not connected" err &&
654 test_line_count = 1 err
655 )
656'
657
658test_expect_success 'bundle progress includes write phase' '
659 GIT_PROGRESS_DELAY=0 \
660 git bundle create --progress out.bundle --all 2>err &&
661 grep 'Writing' err
662'
663
664test_expect_success TTY 'create --quiet disables all bundle progress' '
665 test_terminal env GIT_PROGRESS_DELAY=0 \
666 git bundle create --quiet out.bundle --all 2>err &&
667 test_must_be_empty err
668'
669
670test_expect_success 'bundle progress with --no-quiet' '
671 GIT_PROGRESS_DELAY=0 \
672 git bundle create --no-quiet out.bundle --all 2>err &&
673 grep "%" err
674'
675
676test_expect_success 'create bundle with duplicate refnames' '
677 git bundle create out.bdl "main" "main" &&
678
679 git bundle list-heads out.bdl |
680 make_user_friendly_and_stable_output >actual &&
681 cat >expect <<-\EOF &&
682 <COMMIT-P> refs/heads/main
683 EOF
684 test_cmp expect actual
685'
686
687test_expect_success 'create bundle with duplicate refnames and --all' '
688 git bundle create out.bdl --all "main" "main" &&
689
690 git bundle list-heads out.bdl |
691 make_user_friendly_and_stable_output >actual &&
692 cat >expect <<-\EOF &&
693 <COMMIT-P> refs/heads/main
694 <COMMIT-N> refs/heads/release
695 <COMMIT-D> refs/heads/topic/1
696 <COMMIT-H> refs/heads/topic/2
697 <COMMIT-D> refs/pull/1/head
698 <COMMIT-G> refs/pull/2/head
699 <TAG-1> refs/tags/v1
700 <TAG-2> refs/tags/v2
701 <TAG-3> refs/tags/v3
702 <COMMIT-P> HEAD
703 EOF
704 test_cmp expect actual
705'
706
707test_expect_success 'create bundle with duplicate exlusion refnames' '
708 git bundle create out.bdl "main" "main^!" &&
709
710 git bundle list-heads out.bdl |
711 make_user_friendly_and_stable_output >actual &&
712 cat >expect <<-\EOF &&
713 <COMMIT-P> refs/heads/main
714 EOF
715 test_cmp expect actual
716'
717
718test_expect_success 'create bundle with duplicate refname short-form' '
719 git bundle create out.bdl "main" "main" "refs/heads/main" "refs/heads/main" &&
720
721 git bundle list-heads out.bdl |
722 make_user_friendly_and_stable_output >actual &&
723 cat >expect <<-\EOF &&
724 <COMMIT-P> refs/heads/main
725 EOF
726 test_cmp expect actual
727'
728
729test_expect_success 'read bundle over stdin' '
730 git bundle create some.bundle HEAD &&
731
732 git bundle verify - <some.bundle 2>err &&
733 grep "<stdin> is okay" err &&
734
735 git bundle list-heads some.bundle >expect &&
736 git bundle list-heads - <some.bundle >actual &&
737 test_cmp expect actual &&
738
739 git bundle unbundle some.bundle >expect &&
740 git bundle unbundle - <some.bundle >actual &&
741 test_cmp expect actual
742'
743
744test_expect_success 'send a bundle to standard output' '
745 git bundle create - --all HEAD >bundle-one &&
746 mkdir -p down &&
747 git -C down bundle create - --all HEAD >bundle-two &&
748 git bundle verify bundle-one &&
749 git bundle verify bundle-two &&
750 git ls-remote bundle-one >expect &&
751 git ls-remote bundle-two >actual &&
752 test_cmp expect actual
753'
754
755test_expect_success 'unbundle outside of a repository' '
756 git bundle create some.bundle HEAD &&
757 echo "fatal: Need a repository to unbundle." >expect &&
758 nongit test_must_fail git bundle unbundle "$(pwd)/some.bundle" 2>err &&
759 test_cmp expect err
760'
761
762test_expect_success 'list-heads outside of a repository' '
763 git bundle create some.bundle HEAD &&
764 cat >expect <<-EOF &&
765 $(git rev-parse HEAD) HEAD
766 EOF
767 nongit git bundle list-heads "$(pwd)/some.bundle" >actual &&
768 test_cmp expect actual
769'
770
771for hash in sha1 sha256
772do
773 test_expect_success "list-heads with bundle using $hash" '
774 test_when_finished "rm -rf hash" &&
775 git init --object-format=$hash hash &&
776 test_commit -C hash initial &&
777 git -C hash bundle create hash.bundle HEAD &&
778
779 cat >expect <<-EOF &&
780 $(git -C hash rev-parse HEAD) HEAD
781 EOF
782 git bundle list-heads hash/hash.bundle >actual &&
783 test_cmp expect actual
784 '
785done
786
787test_done