]> git.ipfire.org Git - thirdparty/git.git/blob - t/t6020-bundle-misc.sh
Merge branch 'jt/push-negotiation-fixes' into maint
[thirdparty/git.git] / t / t6020-bundle-misc.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2021 Jiang Xin
4 #
5
6 test_description='Test git-bundle'
7
8 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
9 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
10
11 . ./test-lib.sh
12 . "$TEST_DIRECTORY"/lib-bundle.sh
13
14 # Create a commit or tag and set the variable with the object ID.
15 test_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
83 get_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
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
97 # about future changes of the commit ID.
98 make_user_friendly_and_stable_output () {
99 sed \
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" \
118 -e "s/$(get_abbrev_oid $TAG3)[0-9a-f]*/<TAG-3>/g"
119 }
120
121 format_and_save_expect () {
122 sed -e 's/Z$//' >expect
123 }
124
125 # (C) (D, pull/1/head, topic/1)
126 # o --- o
127 # / \ (L)
128 # / \ o (H, topic/2) (M, tag:v2)
129 # / (F) \ / (N, tag:v3)
130 # / o --------- o (G, pull/2/head) o --- o --- o (release)
131 # / / \ \ / \
132 # o --- o --- o -------- o -- o ------------------ o ------- o --- o (main)
133 # (A) (B) (E, tag:v1) (I) (J) (K) (O) (P)
134 #
135 test_expect_success 'setup' '
136 # Try to make a stable fixed width for abbreviated commit ID,
137 # this fixed-width oid will be replaced with "<OID>".
138 git config core.abbrev 7 &&
139
140 # branch main: commit A & B
141 test_commit_setvar A "Commit A" main.txt &&
142 test_commit_setvar B "Commit B" main.txt &&
143
144 # branch topic/1: commit C & D, refs/pull/1/head
145 git checkout -b topic/1 &&
146 test_commit_setvar C "Commit C" topic-1.txt &&
147 test_commit_setvar D "Commit D" topic-1.txt &&
148 git update-ref refs/pull/1/head HEAD &&
149
150 # branch topic/1: commit E, tag v1
151 git checkout main &&
152 test_commit_setvar E "Commit E" main.txt &&
153 test_commit_setvar --tag TAG1 v1 &&
154
155 # branch topic/2: commit F & G, refs/pull/2/head
156 git checkout -b topic/2 &&
157 test_commit_setvar F "Commit F" topic-2.txt &&
158 test_commit_setvar G "Commit G" topic-2.txt &&
159 git update-ref refs/pull/2/head HEAD &&
160 test_commit_setvar H "Commit H" topic-2.txt &&
161
162 # branch main: merge commit I & J
163 git checkout main &&
164 test_commit_setvar --merge I topic/1 "Merge commit I" &&
165 test_commit_setvar --merge J refs/pull/2/head "Merge commit J" &&
166
167 # branch main: commit K
168 git checkout main &&
169 test_commit_setvar K "Commit K" main.txt &&
170
171 # branch release:
172 git checkout -b release &&
173 test_commit_setvar L "Commit L" release.txt &&
174 test_commit_setvar M "Commit M" release.txt &&
175 test_commit_setvar --tag TAG2 v2 &&
176 test_commit_setvar N "Commit N" release.txt &&
177 test_commit_setvar --tag TAG3 v3 &&
178
179 # branch main: merge commit O, commit P
180 git checkout main &&
181 test_commit_setvar --merge O tags/v2 "Merge commit O" &&
182 test_commit_setvar P "Commit P" main.txt
183 '
184
185 test_expect_success 'create bundle from special rev: main^!' '
186 git bundle create special-rev.bdl "main^!" &&
187
188 git bundle list-heads special-rev.bdl |
189 make_user_friendly_and_stable_output >actual &&
190 cat >expect <<-\EOF &&
191 <COMMIT-P> refs/heads/main
192 EOF
193 test_cmp expect actual &&
194
195 git bundle verify special-rev.bdl |
196 make_user_friendly_and_stable_output >actual &&
197 format_and_save_expect <<-\EOF &&
198 The bundle contains this ref:
199 <COMMIT-P> refs/heads/main
200 The bundle requires this ref:
201 <COMMIT-O> Z
202 EOF
203 test_cmp expect actual &&
204
205 test_bundle_object_count special-rev.bdl 3
206 '
207
208 test_expect_success 'create bundle with --max-count option' '
209 git bundle create max-count.bdl --max-count 1 \
210 main \
211 "^release" \
212 refs/tags/v1 \
213 refs/pull/1/head \
214 refs/pull/2/head &&
215
216 git bundle verify max-count.bdl |
217 make_user_friendly_and_stable_output >actual &&
218 format_and_save_expect <<-\EOF &&
219 The bundle contains these 2 refs:
220 <COMMIT-P> refs/heads/main
221 <TAG-1> refs/tags/v1
222 The bundle requires this ref:
223 <COMMIT-O> Z
224 EOF
225 test_cmp expect actual &&
226
227 test_bundle_object_count max-count.bdl 4
228 '
229
230 test_expect_success 'create bundle with --since option' '
231 git log -1 --pretty="%ad" $M >actual &&
232 cat >expect <<-\EOF &&
233 Thu Apr 7 15:26:13 2005 -0700
234 EOF
235 test_cmp expect actual &&
236
237 git bundle create since.bdl \
238 --since "Thu Apr 7 15:27:00 2005 -0700" \
239 --all &&
240
241 git bundle verify since.bdl |
242 make_user_friendly_and_stable_output >actual &&
243 format_and_save_expect <<-\EOF &&
244 The bundle contains these 5 refs:
245 <COMMIT-P> refs/heads/main
246 <COMMIT-N> refs/heads/release
247 <TAG-2> refs/tags/v2
248 <TAG-3> refs/tags/v3
249 <COMMIT-P> HEAD
250 The bundle requires these 2 refs:
251 <COMMIT-M> Z
252 <COMMIT-K> Z
253 EOF
254 test_cmp expect actual &&
255
256 test_bundle_object_count --thin since.bdl 13
257 '
258
259 test_expect_success 'create bundle 1 - no prerequisites' '
260 # create bundle from args
261 git bundle create 1.bdl topic/1 topic/2 &&
262
263 # create bundle from stdin
264 cat >input <<-\EOF &&
265 topic/1
266 topic/2
267 EOF
268 git bundle create stdin-1.bdl --stdin <input &&
269
270 cat >expect <<-\EOF &&
271 The bundle contains these 2 refs:
272 <COMMIT-D> refs/heads/topic/1
273 <COMMIT-H> refs/heads/topic/2
274 The bundle records a complete history.
275 EOF
276
277 # verify bundle, which has no prerequisites
278 git bundle verify 1.bdl |
279 make_user_friendly_and_stable_output >actual &&
280 test_cmp expect actual &&
281
282 git bundle verify stdin-1.bdl |
283 make_user_friendly_and_stable_output >actual &&
284 test_cmp expect actual &&
285
286 test_bundle_object_count 1.bdl 24 &&
287 test_bundle_object_count stdin-1.bdl 24
288 '
289
290 test_expect_success 'create bundle 2 - has prerequisites' '
291 # create bundle from args
292 git bundle create 2.bdl \
293 --ignore-missing \
294 ^topic/deleted \
295 ^$D \
296 ^topic/2 \
297 release &&
298
299 # create bundle from stdin
300 # input has a non-exist reference: "topic/deleted"
301 cat >input <<-EOF &&
302 ^topic/deleted
303 ^$D
304 ^topic/2
305 EOF
306 git bundle create stdin-2.bdl \
307 --ignore-missing \
308 --stdin \
309 release <input &&
310
311 format_and_save_expect <<-\EOF &&
312 The bundle contains this ref:
313 <COMMIT-N> refs/heads/release
314 The bundle requires these 3 refs:
315 <COMMIT-D> Z
316 <COMMIT-E> Z
317 <COMMIT-G> Z
318 EOF
319
320 git bundle verify 2.bdl |
321 make_user_friendly_and_stable_output >actual &&
322 test_cmp expect actual &&
323
324 git bundle verify stdin-2.bdl |
325 make_user_friendly_and_stable_output >actual &&
326 test_cmp expect actual &&
327
328 test_bundle_object_count 2.bdl 16 &&
329 test_bundle_object_count stdin-2.bdl 16
330 '
331
332 test_expect_success 'fail to verify bundle without prerequisites' '
333 git init --bare test1.git &&
334
335 format_and_save_expect <<-\EOF &&
336 error: Repository lacks these prerequisite commits:
337 error: <COMMIT-D> Z
338 error: <COMMIT-E> Z
339 error: <COMMIT-G> Z
340 EOF
341
342 test_must_fail git -C test1.git bundle verify ../2.bdl 2>&1 |
343 make_user_friendly_and_stable_output >actual &&
344 test_cmp expect actual &&
345
346 test_must_fail git -C test1.git bundle verify ../stdin-2.bdl 2>&1 |
347 make_user_friendly_and_stable_output >actual &&
348 test_cmp expect actual
349 '
350
351 test_expect_success 'create bundle 3 - two refs, same object' '
352 # create bundle from args
353 git bundle create --version=3 3.bdl \
354 ^release \
355 ^topic/1 \
356 ^topic/2 \
357 main \
358 HEAD &&
359
360 # create bundle from stdin
361 cat >input <<-\EOF &&
362 ^release
363 ^topic/1
364 ^topic/2
365 EOF
366 git bundle create --version=3 stdin-3.bdl \
367 --stdin \
368 main HEAD <input &&
369
370 format_and_save_expect <<-\EOF &&
371 The bundle contains these 2 refs:
372 <COMMIT-P> refs/heads/main
373 <COMMIT-P> HEAD
374 The bundle requires these 2 refs:
375 <COMMIT-M> Z
376 <COMMIT-K> Z
377 EOF
378
379 git bundle verify 3.bdl |
380 make_user_friendly_and_stable_output >actual &&
381 test_cmp expect actual &&
382
383 git bundle verify stdin-3.bdl |
384 make_user_friendly_and_stable_output >actual &&
385 test_cmp expect actual &&
386
387 test_bundle_object_count 3.bdl 4 &&
388 test_bundle_object_count stdin-3.bdl 4
389 '
390
391 test_expect_success 'create bundle 4 - with tags' '
392 # create bundle from args
393 git bundle create 4.bdl \
394 ^main \
395 ^release \
396 ^topic/1 \
397 ^topic/2 \
398 --all &&
399
400 # create bundle from stdin
401 cat >input <<-\EOF &&
402 ^main
403 ^release
404 ^topic/1
405 ^topic/2
406 EOF
407 git bundle create stdin-4.bdl \
408 --ignore-missing \
409 --stdin \
410 --all <input &&
411
412 cat >expect <<-\EOF &&
413 The bundle contains these 3 refs:
414 <TAG-1> refs/tags/v1
415 <TAG-2> refs/tags/v2
416 <TAG-3> refs/tags/v3
417 The bundle records a complete history.
418 EOF
419
420 git bundle verify 4.bdl |
421 make_user_friendly_and_stable_output >actual &&
422 test_cmp expect actual &&
423
424 git bundle verify stdin-4.bdl |
425 make_user_friendly_and_stable_output >actual &&
426 test_cmp expect actual &&
427
428 test_bundle_object_count 4.bdl 3 &&
429 test_bundle_object_count stdin-4.bdl 3
430 '
431
432 test_expect_success 'clone from bundle' '
433 git clone --mirror 1.bdl mirror.git &&
434 git -C mirror.git show-ref |
435 make_user_friendly_and_stable_output >actual &&
436 cat >expect <<-\EOF &&
437 <COMMIT-D> refs/heads/topic/1
438 <COMMIT-H> refs/heads/topic/2
439 EOF
440 test_cmp expect actual &&
441
442 git -C mirror.git fetch ../2.bdl "+refs/*:refs/*" &&
443 git -C mirror.git show-ref |
444 make_user_friendly_and_stable_output >actual &&
445 cat >expect <<-\EOF &&
446 <COMMIT-N> refs/heads/release
447 <COMMIT-D> refs/heads/topic/1
448 <COMMIT-H> refs/heads/topic/2
449 EOF
450 test_cmp expect actual &&
451
452 git -C mirror.git fetch ../3.bdl "+refs/*:refs/*" &&
453 git -C mirror.git show-ref |
454 make_user_friendly_and_stable_output >actual &&
455 cat >expect <<-\EOF &&
456 <COMMIT-P> refs/heads/main
457 <COMMIT-N> refs/heads/release
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 ../4.bdl "+refs/*:refs/*" &&
464 git -C mirror.git show-ref |
465 make_user_friendly_and_stable_output >actual &&
466 cat >expect <<-\EOF &&
467 <COMMIT-P> refs/heads/main
468 <COMMIT-N> refs/heads/release
469 <COMMIT-D> refs/heads/topic/1
470 <COMMIT-H> refs/heads/topic/2
471 <TAG-1> refs/tags/v1
472 <TAG-2> refs/tags/v2
473 <TAG-3> refs/tags/v3
474 EOF
475 test_cmp expect actual
476 '
477
478 test_done