]> git.ipfire.org Git - thirdparty/git.git/blame - t/t6020-bundle-misc.sh
Sync with 2.36.3
[thirdparty/git.git] / t / t6020-bundle-misc.sh
CommitLineData
9901164d
JX
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
e8a8e7ff 12. "$TEST_DIRECTORY"/lib-bundle.sh
9901164d
JX
13
14# Create a commit or tag and set the variable with the object ID.
15test_commit_setvar () {
16 notick=
17 signoff=
18 indir=
19 merge=
20 tag=
21 var=
22
23 while test $# != 0
24 do
25 case "$1" in
26 --merge)
27 merge=t
28 ;;
29 --tag)
30 tag=t
31 ;;
32 --notick)
33 notick=t
34 ;;
35 --signoff)
36 signoff="$1"
37 ;;
38 -C)
39 shift
40 indir="$1"
41 ;;
42 -*)
43 echo >&2 "error: unknown option $1"
44 return 1
45 ;;
46 *)
47 break
48 ;;
49 esac
50 shift
51 done
52 if test $# -lt 2
53 then
54 echo >&2 "error: test_commit_setvar must have at least 2 arguments"
55 return 1
56 fi
57 var=$1
58 shift
59 indir=${indir:+"$indir"/}
60 if test -z "$notick"
61 then
62 test_tick
63 fi &&
64 if test -n "$merge"
65 then
66 git ${indir:+ -C "$indir"} merge --no-edit --no-ff \
67 ${2:+-m "$2"} "$1" &&
68 oid=$(git ${indir:+ -C "$indir"} rev-parse HEAD)
69 elif test -n "$tag"
70 then
71 git ${indir:+ -C "$indir"} tag -m "$1" "$1" "${2:-HEAD}" &&
72 oid=$(git ${indir:+ -C "$indir"} rev-parse "$1")
73 else
74 file=${2:-"$1.t"} &&
75 echo "${3-$1}" >"$indir$file" &&
76 git ${indir:+ -C "$indir"} add "$file" &&
77 git ${indir:+ -C "$indir"} commit $signoff -m "$1" &&
78 oid=$(git ${indir:+ -C "$indir"} rev-parse HEAD)
79 fi &&
80 eval $var=$oid
81}
82
eb87c6f5
JX
83get_abbrev_oid () {
84 oid=$1 &&
85 suffix=${oid#???????} &&
86 oid=${oid%$suffix} &&
87 if test -n "$oid"
88 then
89 echo "$oid"
90 else
91 echo "undefined-oid"
92 fi
93}
94
9901164d
JX
95# Format the output of git commands to make a user-friendly and stable
96# text. We can easily prepare the expect text without having to worry
2bafb3d7 97# about future changes of the commit ID.
9901164d
JX
98make_user_friendly_and_stable_output () {
99 sed \
eb87c6f5
JX
100 -e "s/$(get_abbrev_oid $A)[0-9a-f]*/<COMMIT-A>/g" \
101 -e "s/$(get_abbrev_oid $B)[0-9a-f]*/<COMMIT-B>/g" \
102 -e "s/$(get_abbrev_oid $C)[0-9a-f]*/<COMMIT-C>/g" \
103 -e "s/$(get_abbrev_oid $D)[0-9a-f]*/<COMMIT-D>/g" \
104 -e "s/$(get_abbrev_oid $E)[0-9a-f]*/<COMMIT-E>/g" \
105 -e "s/$(get_abbrev_oid $F)[0-9a-f]*/<COMMIT-F>/g" \
106 -e "s/$(get_abbrev_oid $G)[0-9a-f]*/<COMMIT-G>/g" \
107 -e "s/$(get_abbrev_oid $H)[0-9a-f]*/<COMMIT-H>/g" \
108 -e "s/$(get_abbrev_oid $I)[0-9a-f]*/<COMMIT-I>/g" \
109 -e "s/$(get_abbrev_oid $J)[0-9a-f]*/<COMMIT-J>/g" \
110 -e "s/$(get_abbrev_oid $K)[0-9a-f]*/<COMMIT-K>/g" \
111 -e "s/$(get_abbrev_oid $L)[0-9a-f]*/<COMMIT-L>/g" \
112 -e "s/$(get_abbrev_oid $M)[0-9a-f]*/<COMMIT-M>/g" \
113 -e "s/$(get_abbrev_oid $N)[0-9a-f]*/<COMMIT-N>/g" \
114 -e "s/$(get_abbrev_oid $O)[0-9a-f]*/<COMMIT-O>/g" \
115 -e "s/$(get_abbrev_oid $P)[0-9a-f]*/<COMMIT-P>/g" \
116 -e "s/$(get_abbrev_oid $TAG1)[0-9a-f]*/<TAG-1>/g" \
117 -e "s/$(get_abbrev_oid $TAG2)[0-9a-f]*/<TAG-2>/g" \
7cc11473 118 -e "s/$(get_abbrev_oid $TAG3)[0-9a-f]*/<TAG-3>/g"
2bafb3d7
JX
119}
120
121format_and_save_expect () {
122 sed -e 's/Z$//' >expect
9901164d
JX
123}
124
8ba221e2
DS
125HASH_MESSAGE="The bundle uses this hash algorithm: $GIT_DEFAULT_HASH"
126
9901164d
JX
127# (C) (D, pull/1/head, topic/1)
128# o --- o
129# / \ (L)
130# / \ o (H, topic/2) (M, tag:v2)
131# / (F) \ / (N, tag:v3)
132# / o --------- o (G, pull/2/head) o --- o --- o (release)
133# / / \ \ / \
134# o --- o --- o -------- o -- o ------------------ o ------- o --- o (main)
135# (A) (B) (E, tag:v1) (I) (J) (K) (O) (P)
136#
137test_expect_success 'setup' '
138 # Try to make a stable fixed width for abbreviated commit ID,
139 # this fixed-width oid will be replaced with "<OID>".
140 git config core.abbrev 7 &&
141
142 # branch main: commit A & B
143 test_commit_setvar A "Commit A" main.txt &&
144 test_commit_setvar B "Commit B" main.txt &&
145
146 # branch topic/1: commit C & D, refs/pull/1/head
147 git checkout -b topic/1 &&
148 test_commit_setvar C "Commit C" topic-1.txt &&
149 test_commit_setvar D "Commit D" topic-1.txt &&
150 git update-ref refs/pull/1/head HEAD &&
151
152 # branch topic/1: commit E, tag v1
153 git checkout main &&
154 test_commit_setvar E "Commit E" main.txt &&
155 test_commit_setvar --tag TAG1 v1 &&
156
157 # branch topic/2: commit F & G, refs/pull/2/head
158 git checkout -b topic/2 &&
159 test_commit_setvar F "Commit F" topic-2.txt &&
160 test_commit_setvar G "Commit G" topic-2.txt &&
161 git update-ref refs/pull/2/head HEAD &&
162 test_commit_setvar H "Commit H" topic-2.txt &&
163
164 # branch main: merge commit I & J
165 git checkout main &&
166 test_commit_setvar --merge I topic/1 "Merge commit I" &&
167 test_commit_setvar --merge J refs/pull/2/head "Merge commit J" &&
168
169 # branch main: commit K
170 git checkout main &&
171 test_commit_setvar K "Commit K" main.txt &&
172
173 # branch release:
174 git checkout -b release &&
175 test_commit_setvar L "Commit L" release.txt &&
176 test_commit_setvar M "Commit M" release.txt &&
177 test_commit_setvar --tag TAG2 v2 &&
178 test_commit_setvar N "Commit N" release.txt &&
179 test_commit_setvar --tag TAG3 v3 &&
180
181 # branch main: merge commit O, commit P
182 git checkout main &&
183 test_commit_setvar --merge O tags/v2 "Merge commit O" &&
184 test_commit_setvar P "Commit P" main.txt
185'
186
ce1d6d9f 187test_expect_success 'create bundle from special rev: main^!' '
9901164d
JX
188 git bundle create special-rev.bdl "main^!" &&
189
190 git bundle list-heads special-rev.bdl |
191 make_user_friendly_and_stable_output >actual &&
192 cat >expect <<-\EOF &&
193 <COMMIT-P> refs/heads/main
194 EOF
1108cea7 195 test_cmp expect actual &&
9901164d
JX
196
197 git bundle verify special-rev.bdl |
198 make_user_friendly_and_stable_output >actual &&
8ba221e2 199 format_and_save_expect <<-EOF &&
9901164d
JX
200 The bundle contains this ref:
201 <COMMIT-P> refs/heads/main
202 The bundle requires this ref:
2bafb3d7 203 <COMMIT-O> Z
8ba221e2 204 $HASH_MESSAGE
9901164d 205 EOF
1108cea7 206 test_cmp expect actual &&
9901164d
JX
207
208 test_bundle_object_count special-rev.bdl 3
209'
210
211test_expect_success 'create bundle with --max-count option' '
212 git bundle create max-count.bdl --max-count 1 \
213 main \
214 "^release" \
215 refs/tags/v1 \
216 refs/pull/1/head \
217 refs/pull/2/head &&
218
219 git bundle verify max-count.bdl |
220 make_user_friendly_and_stable_output >actual &&
8ba221e2 221 format_and_save_expect <<-EOF &&
9901164d
JX
222 The bundle contains these 2 refs:
223 <COMMIT-P> refs/heads/main
224 <TAG-1> refs/tags/v1
225 The bundle requires this ref:
2bafb3d7 226 <COMMIT-O> Z
8ba221e2 227 $HASH_MESSAGE
9901164d 228 EOF
1108cea7 229 test_cmp expect actual &&
9901164d
JX
230
231 test_bundle_object_count max-count.bdl 4
232'
233
234test_expect_success 'create bundle with --since option' '
235 git log -1 --pretty="%ad" $M >actual &&
236 cat >expect <<-\EOF &&
237 Thu Apr 7 15:26:13 2005 -0700
238 EOF
239 test_cmp expect actual &&
240
241 git bundle create since.bdl \
242 --since "Thu Apr 7 15:27:00 2005 -0700" \
243 --all &&
244
245 git bundle verify since.bdl |
246 make_user_friendly_and_stable_output >actual &&
8ba221e2 247 format_and_save_expect <<-EOF &&
9901164d
JX
248 The bundle contains these 5 refs:
249 <COMMIT-P> refs/heads/main
250 <COMMIT-N> refs/heads/release
251 <TAG-2> refs/tags/v2
252 <TAG-3> refs/tags/v3
253 <COMMIT-P> HEAD
254 The bundle requires these 2 refs:
2bafb3d7
JX
255 <COMMIT-M> Z
256 <COMMIT-K> Z
8ba221e2 257 $HASH_MESSAGE
9901164d 258 EOF
1108cea7 259 test_cmp expect actual &&
9901164d
JX
260
261 test_bundle_object_count --thin since.bdl 13
262'
263
264test_expect_success 'create bundle 1 - no prerequisites' '
5bb0fd2c 265 # create bundle from args
9901164d
JX
266 git bundle create 1.bdl topic/1 topic/2 &&
267
5bb0fd2c
JX
268 # create bundle from stdin
269 cat >input <<-\EOF &&
270 topic/1
271 topic/2
272 EOF
273 git bundle create stdin-1.bdl --stdin <input &&
274
8ba221e2 275 format_and_save_expect <<-EOF &&
9901164d
JX
276 The bundle contains these 2 refs:
277 <COMMIT-D> refs/heads/topic/1
278 <COMMIT-H> refs/heads/topic/2
279 The bundle records a complete history.
8ba221e2 280 $HASH_MESSAGE
9901164d
JX
281 EOF
282
283 # verify bundle, which has no prerequisites
284 git bundle verify 1.bdl |
285 make_user_friendly_and_stable_output >actual &&
1108cea7 286 test_cmp expect actual &&
9901164d 287
5bb0fd2c
JX
288 git bundle verify stdin-1.bdl |
289 make_user_friendly_and_stable_output >actual &&
1108cea7 290 test_cmp expect actual &&
5bb0fd2c
JX
291
292 test_bundle_object_count 1.bdl 24 &&
293 test_bundle_object_count stdin-1.bdl 24
9901164d
JX
294'
295
296test_expect_success 'create bundle 2 - has prerequisites' '
5bb0fd2c 297 # create bundle from args
9901164d
JX
298 git bundle create 2.bdl \
299 --ignore-missing \
300 ^topic/deleted \
301 ^$D \
302 ^topic/2 \
303 release &&
304
5bb0fd2c
JX
305 # create bundle from stdin
306 # input has a non-exist reference: "topic/deleted"
307 cat >input <<-EOF &&
308 ^topic/deleted
309 ^$D
310 ^topic/2
311 EOF
312 git bundle create stdin-2.bdl \
313 --ignore-missing \
314 --stdin \
315 release <input &&
316
8ba221e2 317 format_and_save_expect <<-EOF &&
9901164d
JX
318 The bundle contains this ref:
319 <COMMIT-N> refs/heads/release
320 The bundle requires these 3 refs:
2bafb3d7
JX
321 <COMMIT-D> Z
322 <COMMIT-E> Z
323 <COMMIT-G> Z
8ba221e2 324 $HASH_MESSAGE
9901164d
JX
325 EOF
326
327 git bundle verify 2.bdl |
328 make_user_friendly_and_stable_output >actual &&
1108cea7 329 test_cmp expect actual &&
9901164d 330
5bb0fd2c
JX
331 git bundle verify stdin-2.bdl |
332 make_user_friendly_and_stable_output >actual &&
1108cea7 333 test_cmp expect actual &&
5bb0fd2c
JX
334
335 test_bundle_object_count 2.bdl 16 &&
336 test_bundle_object_count stdin-2.bdl 16
9901164d
JX
337'
338
339test_expect_success 'fail to verify bundle without prerequisites' '
340 git init --bare test1.git &&
341
2bafb3d7 342 format_and_save_expect <<-\EOF &&
9901164d 343 error: Repository lacks these prerequisite commits:
2bafb3d7
JX
344 error: <COMMIT-D> Z
345 error: <COMMIT-E> Z
346 error: <COMMIT-G> Z
9901164d
JX
347 EOF
348
349 test_must_fail git -C test1.git bundle verify ../2.bdl 2>&1 |
350 make_user_friendly_and_stable_output >actual &&
1108cea7 351 test_cmp expect actual &&
5bb0fd2c
JX
352
353 test_must_fail git -C test1.git bundle verify ../stdin-2.bdl 2>&1 |
354 make_user_friendly_and_stable_output >actual &&
1108cea7 355 test_cmp expect actual
9901164d
JX
356'
357
358test_expect_success 'create bundle 3 - two refs, same object' '
5bb0fd2c 359 # create bundle from args
9901164d
JX
360 git bundle create --version=3 3.bdl \
361 ^release \
362 ^topic/1 \
363 ^topic/2 \
364 main \
365 HEAD &&
366
5bb0fd2c
JX
367 # create bundle from stdin
368 cat >input <<-\EOF &&
369 ^release
370 ^topic/1
371 ^topic/2
372 EOF
373 git bundle create --version=3 stdin-3.bdl \
374 --stdin \
375 main HEAD <input &&
376
8ba221e2 377 format_and_save_expect <<-EOF &&
9901164d
JX
378 The bundle contains these 2 refs:
379 <COMMIT-P> refs/heads/main
380 <COMMIT-P> HEAD
381 The bundle requires these 2 refs:
2bafb3d7
JX
382 <COMMIT-M> Z
383 <COMMIT-K> Z
8ba221e2 384 $HASH_MESSAGE
9901164d
JX
385 EOF
386
387 git bundle verify 3.bdl |
388 make_user_friendly_and_stable_output >actual &&
1108cea7 389 test_cmp expect actual &&
9901164d 390
5bb0fd2c
JX
391 git bundle verify stdin-3.bdl |
392 make_user_friendly_and_stable_output >actual &&
1108cea7 393 test_cmp expect actual &&
5bb0fd2c
JX
394
395 test_bundle_object_count 3.bdl 4 &&
396 test_bundle_object_count stdin-3.bdl 4
9901164d
JX
397'
398
399test_expect_success 'create bundle 4 - with tags' '
5bb0fd2c 400 # create bundle from args
9901164d
JX
401 git bundle create 4.bdl \
402 ^main \
403 ^release \
404 ^topic/1 \
405 ^topic/2 \
406 --all &&
407
5bb0fd2c
JX
408 # create bundle from stdin
409 cat >input <<-\EOF &&
410 ^main
411 ^release
412 ^topic/1
413 ^topic/2
414 EOF
415 git bundle create stdin-4.bdl \
416 --ignore-missing \
417 --stdin \
418 --all <input &&
419
8ba221e2 420 cat >expect <<-EOF &&
9901164d
JX
421 The bundle contains these 3 refs:
422 <TAG-1> refs/tags/v1
423 <TAG-2> refs/tags/v2
424 <TAG-3> refs/tags/v3
425 The bundle records a complete history.
8ba221e2 426 $HASH_MESSAGE
9901164d
JX
427 EOF
428
429 git bundle verify 4.bdl |
430 make_user_friendly_and_stable_output >actual &&
1108cea7 431 test_cmp expect actual &&
9901164d 432
5bb0fd2c
JX
433 git bundle verify stdin-4.bdl |
434 make_user_friendly_and_stable_output >actual &&
1108cea7 435 test_cmp expect actual &&
5bb0fd2c
JX
436
437 test_bundle_object_count 4.bdl 3 &&
438 test_bundle_object_count stdin-4.bdl 3
9901164d
JX
439'
440
441test_expect_success 'clone from bundle' '
442 git clone --mirror 1.bdl mirror.git &&
443 git -C mirror.git show-ref |
444 make_user_friendly_and_stable_output >actual &&
445 cat >expect <<-\EOF &&
446 <COMMIT-D> refs/heads/topic/1
447 <COMMIT-H> refs/heads/topic/2
448 EOF
449 test_cmp expect actual &&
450
451 git -C mirror.git fetch ../2.bdl "+refs/*:refs/*" &&
452 git -C mirror.git show-ref |
453 make_user_friendly_and_stable_output >actual &&
454 cat >expect <<-\EOF &&
455 <COMMIT-N> refs/heads/release
456 <COMMIT-D> refs/heads/topic/1
457 <COMMIT-H> refs/heads/topic/2
458 EOF
459 test_cmp expect actual &&
460
461 git -C mirror.git fetch ../3.bdl "+refs/*:refs/*" &&
462 git -C mirror.git show-ref |
463 make_user_friendly_and_stable_output >actual &&
464 cat >expect <<-\EOF &&
465 <COMMIT-P> refs/heads/main
466 <COMMIT-N> refs/heads/release
467 <COMMIT-D> refs/heads/topic/1
468 <COMMIT-H> refs/heads/topic/2
469 EOF
470 test_cmp expect actual &&
471
472 git -C mirror.git fetch ../4.bdl "+refs/*:refs/*" &&
473 git -C mirror.git show-ref |
474 make_user_friendly_and_stable_output >actual &&
475 cat >expect <<-\EOF &&
476 <COMMIT-P> refs/heads/main
477 <COMMIT-N> refs/heads/release
478 <COMMIT-D> refs/heads/topic/1
479 <COMMIT-H> refs/heads/topic/2
480 <TAG-1> refs/tags/v1
481 <TAG-2> refs/tags/v2
482 <TAG-3> refs/tags/v3
483 EOF
484 test_cmp expect actual
485'
486
4f33a634
ÆAB
487test_expect_success 'unfiltered bundle with --objects' '
488 git bundle create all-objects.bdl \
489 --all --objects &&
490 git bundle create all.bdl \
491 --all &&
492
493 # Compare the headers of these files.
494 sed -n -e "/^$/q" -e "p" all.bdl >expect &&
495 sed -n -e "/^$/q" -e "p" all-objects.bdl >actual &&
496 test_cmp expect actual
497'
498
f18b512b
DS
499for filter in "blob:none" "tree:0" "tree:1" "blob:limit=100"
500do
501 test_expect_success "filtered bundle: $filter" '
502 test_when_finished rm -rf .git/objects/pack cloned unbundled &&
503 git bundle create partial.bdl \
504 --all \
505 --filter=$filter &&
506
507 git bundle verify partial.bdl >unfiltered &&
508 make_user_friendly_and_stable_output <unfiltered >actual &&
509
510 cat >expect <<-EOF &&
511 The bundle contains these 10 refs:
512 <COMMIT-P> refs/heads/main
513 <COMMIT-N> refs/heads/release
514 <COMMIT-D> refs/heads/topic/1
515 <COMMIT-H> refs/heads/topic/2
516 <COMMIT-D> refs/pull/1/head
517 <COMMIT-G> refs/pull/2/head
518 <TAG-1> refs/tags/v1
519 <TAG-2> refs/tags/v2
520 <TAG-3> refs/tags/v3
521 <COMMIT-P> HEAD
f18b512b 522 The bundle records a complete history.
8ba221e2 523 $HASH_MESSAGE
017303eb 524 The bundle uses this filter: $filter
f18b512b
DS
525 EOF
526 test_cmp expect actual &&
527
528 test_config uploadpack.allowfilter 1 &&
529 test_config uploadpack.allowanysha1inwant 1 &&
530 git clone --no-local --filter=$filter --bare "file://$(pwd)" cloned &&
531
532 git init unbundled &&
533 git -C unbundled bundle unbundle ../partial.bdl >ref-list.txt &&
4f39eb03
DS
534 ls unbundled/.git/objects/pack/pack-*.promisor >promisor &&
535 test_line_count = 1 promisor &&
f18b512b
DS
536
537 # Count the same number of reachable objects.
538 reflist=$(git for-each-ref --format="%(objectname)") &&
539 git rev-list --objects --filter=$filter --missing=allow-any \
540 $reflist >expect &&
541 for repo in cloned unbundled
542 do
543 git -C $repo rev-list --objects --missing=allow-any \
544 $reflist >actual &&
545 test_cmp expect actual || return 1
546 done
547 '
548done
549
86fdd94d
DS
550# NEEDSWORK: 'git clone --bare' should be able to clone from a filtered
551# bundle, but that requires a change to promisor/filter config options.
552# For now, we fail gracefully with a helpful error. This behavior can be
553# changed in the future to succeed as much as possible.
554test_expect_success 'cloning from filtered bundle has useful error' '
555 git bundle create partial.bdl \
556 --all \
557 --filter=blob:none &&
558 test_must_fail git clone --bare partial.bdl partial 2>err &&
559 grep "cannot clone from filtered bundle" err
560'
561
9901164d 562test_done