test: add helper functions for git-bundle

Move git-bundle related functions from t5510 to a library, and this lib will be shared with a new testcase t6020 which finds a known breakage of "git-bundle". Signed-off-by: Jiang Xin <zhiyou.jx@alibaba-inc.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jiang Xin committed Jan 11, 2021 at 21:27 UTC 9901164d81dfc2e050860f7dd60e5590c3cfaa50
3 files changed +440 -22
t/t5510-fetch.sh
+4 -22
@@ -6,22 +6,10 @@ test_description='Per branch config variables affects "git fetch".
6 '
7
8 . ./test-lib.sh
9 +. "$TEST_DIRECTORY"/test-bundle-functions.sh
10
11 D=$(pwd)
12
12 -test_bundle_object_count () {
13 - git verify-pack -v "$1" >verify.out &&
14 - test "$2" = $(grep "^$OID_REGEX " verify.out | wc -l)
15 -}
16 -
17 -convert_bundle_to_pack () {
18 - while read x && test -n "$x"
19 - do
20 - :;
21 - done
22 - cat
23 -}
24 -
13 test_expect_success setup '
14 echo >file original &&
15 git add file &&
@@ -312,9 +300,7 @@ test_expect_success 'unbundle 1' '
300
301 test_expect_success 'bundle 1 has only 3 files ' '
302 cd "$D" &&
315 - convert_bundle_to_pack <bundle1 >bundle.pack &&
316 - git index-pack bundle.pack &&
317 - test_bundle_object_count bundle.pack 3
303 + test_bundle_object_count bundle1 3
304 '
305
306 test_expect_success 'unbundle 2' '
@@ -329,9 +315,7 @@ test_expect_success 'bundle does not prerequisite objects' '
315 git add file2 &&
316 git commit -m add.file2 file2 &&
317 git bundle create bundle3 -1 HEAD &&
332 - convert_bundle_to_pack <bundle3 >bundle.pack &&
333 - git index-pack bundle.pack &&
334 - test_bundle_object_count bundle.pack 3
318 + test_bundle_object_count bundle3 3
319 '
320
321 test_expect_success 'bundle should be able to create a full history' '
@@ -884,9 +868,7 @@ test_expect_success 'all boundary commits are excluded' '
868 git merge otherside &&
869 ad=$(git log --no-walk --format=%ad HEAD) &&
870 git bundle create twoside-boundary.bdl main --since="$ad" &&
887 - convert_bundle_to_pack <twoside-boundary.bdl >twoside-boundary.pack &&
888 - pack=$(git index-pack --fix-thin --stdin <twoside-boundary.pack) &&
889 - test_bundle_object_count .git/objects/pack/pack-${pack##pack }.pack 3
871 + test_bundle_object_count --thin twoside-boundary.bdl 3
872 '
873
874 test_expect_success 'fetch --prune prints the remotes url' '
t/t6020-bundle-misc.sh new
+394
@@ -0,0 +1,394 @@
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"/test-bundle-functions.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 +# Format the output of git commands to make a user-friendly and stable
84 +# text. We can easily prepare the expect text without having to worry
85 +# about future changes of the commit ID and spaces of the output.
86 +make_user_friendly_and_stable_output () {
87 + sed \
88 + -e "s/${A%${A#???????}}[0-9a-f]*/<COMMIT-A>/g" \
89 + -e "s/${B%${B#???????}}[0-9a-f]*/<COMMIT-B>/g" \
90 + -e "s/${C%${C#???????}}[0-9a-f]*/<COMMIT-C>/g" \
91 + -e "s/${D%${D#???????}}[0-9a-f]*/<COMMIT-D>/g" \
92 + -e "s/${E%${E#???????}}[0-9a-f]*/<COMMIT-E>/g" \
93 + -e "s/${F%${F#???????}}[0-9a-f]*/<COMMIT-F>/g" \
94 + -e "s/${G%${G#???????}}[0-9a-f]*/<COMMIT-G>/g" \
95 + -e "s/${H%${H#???????}}[0-9a-f]*/<COMMIT-H>/g" \
96 + -e "s/${I%${I#???????}}[0-9a-f]*/<COMMIT-I>/g" \
97 + -e "s/${J%${J#???????}}[0-9a-f]*/<COMMIT-J>/g" \
98 + -e "s/${K%${K#???????}}[0-9a-f]*/<COMMIT-K>/g" \
99 + -e "s/${L%${L#???????}}[0-9a-f]*/<COMMIT-L>/g" \
100 + -e "s/${M%${M#???????}}[0-9a-f]*/<COMMIT-M>/g" \
101 + -e "s/${N%${N#???????}}[0-9a-f]*/<COMMIT-N>/g" \
102 + -e "s/${O%${O#???????}}[0-9a-f]*/<COMMIT-O>/g" \
103 + -e "s/${P%${P#???????}}[0-9a-f]*/<COMMIT-P>/g" \
104 + -e "s/${TAG1%${TAG1#???????}}[0-9a-f]*/<TAG-1>/g" \
105 + -e "s/${TAG2%${TAG2#???????}}[0-9a-f]*/<TAG-2>/g" \
106 + -e "s/${TAG3%${TAG3#???????}}[0-9a-f]*/<TAG-3>/g" \
107 + -e "s/ *\$//"
108 +}
109 +
110 +# (C) (D, pull/1/head, topic/1)
111 +# o --- o
112 +# / \ (L)
113 +# / \ o (H, topic/2) (M, tag:v2)
114 +# / (F) \ / (N, tag:v3)
115 +# / o --------- o (G, pull/2/head) o --- o --- o (release)
116 +# / / \ \ / \
117 +# o --- o --- o -------- o -- o ------------------ o ------- o --- o (main)
118 +# (A) (B) (E, tag:v1) (I) (J) (K) (O) (P)
119 +#
120 +test_expect_success 'setup' '
121 + # Try to make a stable fixed width for abbreviated commit ID,
122 + # this fixed-width oid will be replaced with "<OID>".
123 + git config core.abbrev 7 &&
124 +
125 + # branch main: commit A & B
126 + test_commit_setvar A "Commit A" main.txt &&
127 + test_commit_setvar B "Commit B" main.txt &&
128 +
129 + # branch topic/1: commit C & D, refs/pull/1/head
130 + git checkout -b topic/1 &&
131 + test_commit_setvar C "Commit C" topic-1.txt &&
132 + test_commit_setvar D "Commit D" topic-1.txt &&
133 + git update-ref refs/pull/1/head HEAD &&
134 +
135 + # branch topic/1: commit E, tag v1
136 + git checkout main &&
137 + test_commit_setvar E "Commit E" main.txt &&
138 + test_commit_setvar --tag TAG1 v1 &&
139 +
140 + # branch topic/2: commit F & G, refs/pull/2/head
141 + git checkout -b topic/2 &&
142 + test_commit_setvar F "Commit F" topic-2.txt &&
143 + test_commit_setvar G "Commit G" topic-2.txt &&
144 + git update-ref refs/pull/2/head HEAD &&
145 + test_commit_setvar H "Commit H" topic-2.txt &&
146 +
147 + # branch main: merge commit I & J
148 + git checkout main &&
149 + test_commit_setvar --merge I topic/1 "Merge commit I" &&
150 + test_commit_setvar --merge J refs/pull/2/head "Merge commit J" &&
151 +
152 + # branch main: commit K
153 + git checkout main &&
154 + test_commit_setvar K "Commit K" main.txt &&
155 +
156 + # branch release:
157 + git checkout -b release &&
158 + test_commit_setvar L "Commit L" release.txt &&
159 + test_commit_setvar M "Commit M" release.txt &&
160 + test_commit_setvar --tag TAG2 v2 &&
161 + test_commit_setvar N "Commit N" release.txt &&
162 + test_commit_setvar --tag TAG3 v3 &&
163 +
164 + # branch main: merge commit O, commit P
165 + git checkout main &&
166 + test_commit_setvar --merge O tags/v2 "Merge commit O" &&
167 + test_commit_setvar P "Commit P" main.txt
168 +'
169 +
170 +test_expect_failure 'create bundle from special rev: main^!' '
171 + git bundle create special-rev.bdl "main^!" &&
172 +
173 + git bundle list-heads special-rev.bdl |
174 + make_user_friendly_and_stable_output >actual &&
175 + cat >expect <<-\EOF &&
176 + <COMMIT-P> refs/heads/main
177 + EOF
178 + test_i18ncmp expect actual &&
179 +
180 + git bundle verify special-rev.bdl |
181 + make_user_friendly_and_stable_output >actual &&
182 + cat >expect <<-\EOF &&
183 + The bundle contains this ref:
184 + <COMMIT-P> refs/heads/main
185 + The bundle requires this ref:
186 + <COMMIT-O>
187 + EOF
188 + test_i18ncmp expect actual &&
189 +
190 + test_bundle_object_count special-rev.bdl 3
191 +'
192 +
193 +test_expect_success 'create bundle with --max-count option' '
194 + git bundle create max-count.bdl --max-count 1 \
195 + main \
196 + "^release" \
197 + refs/tags/v1 \
198 + refs/pull/1/head \
199 + refs/pull/2/head &&
200 +
201 + git bundle verify max-count.bdl |
202 + make_user_friendly_and_stable_output >actual &&
203 + cat >expect <<-\EOF &&
204 + The bundle contains these 2 refs:
205 + <COMMIT-P> refs/heads/main
206 + <TAG-1> refs/tags/v1
207 + The bundle requires this ref:
208 + <COMMIT-O>
209 + EOF
210 + test_i18ncmp expect actual &&
211 +
212 + test_bundle_object_count max-count.bdl 4
213 +'
214 +
215 +test_expect_success 'create bundle with --since option' '
216 + git log -1 --pretty="%ad" $M >actual &&
217 + cat >expect <<-\EOF &&
218 + Thu Apr 7 15:26:13 2005 -0700
219 + EOF
220 + test_cmp expect actual &&
221 +
222 + git bundle create since.bdl \
223 + --since "Thu Apr 7 15:27:00 2005 -0700" \
224 + --all &&
225 +
226 + git bundle verify since.bdl |
227 + make_user_friendly_and_stable_output >actual &&
228 + cat >expect <<-\EOF &&
229 + The bundle contains these 5 refs:
230 + <COMMIT-P> refs/heads/main
231 + <COMMIT-N> refs/heads/release
232 + <TAG-2> refs/tags/v2
233 + <TAG-3> refs/tags/v3
234 + <COMMIT-P> HEAD
235 + The bundle requires these 2 refs:
236 + <COMMIT-M>
237 + <COMMIT-K>
238 + EOF
239 + test_i18ncmp expect actual &&
240 +
241 + test_bundle_object_count --thin since.bdl 13
242 +'
243 +
244 +test_expect_success 'create bundle 1 - no prerequisites' '
245 + git bundle create 1.bdl topic/1 topic/2 &&
246 +
247 + cat >expect <<-\EOF &&
248 + The bundle contains these 2 refs:
249 + <COMMIT-D> refs/heads/topic/1
250 + <COMMIT-H> refs/heads/topic/2
251 + The bundle records a complete history.
252 + EOF
253 +
254 + # verify bundle, which has no prerequisites
255 + git bundle verify 1.bdl |
256 + make_user_friendly_and_stable_output >actual &&
257 + test_i18ncmp expect actual &&
258 +
259 + test_bundle_object_count 1.bdl 24
260 +'
261 +
262 +test_expect_success 'create bundle 2 - has prerequisites' '
263 + git bundle create 2.bdl \
264 + --ignore-missing \
265 + ^topic/deleted \
266 + ^$D \
267 + ^topic/2 \
268 + release &&
269 +
270 + cat >expect <<-\EOF &&
271 + The bundle contains this ref:
272 + <COMMIT-N> refs/heads/release
273 + The bundle requires these 3 refs:
274 + <COMMIT-D>
275 + <COMMIT-E>
276 + <COMMIT-G>
277 + EOF
278 +
279 + git bundle verify 2.bdl |
280 + make_user_friendly_and_stable_output >actual &&
281 + test_i18ncmp expect actual &&
282 +
283 + test_bundle_object_count 2.bdl 16
284 +'
285 +
286 +test_expect_success 'fail to verify bundle without prerequisites' '
287 + git init --bare test1.git &&
288 +
289 + cat >expect <<-\EOF &&
290 + error: Repository lacks these prerequisite commits:
291 + error: <COMMIT-D>
292 + error: <COMMIT-E>
293 + error: <COMMIT-G>
294 + EOF
295 +
296 + test_must_fail git -C test1.git bundle verify ../2.bdl 2>&1 |
297 + make_user_friendly_and_stable_output >actual &&
298 + test_i18ncmp expect actual
299 +'
300 +
301 +test_expect_success 'create bundle 3 - two refs, same object' '
302 + git bundle create --version=3 3.bdl \
303 + ^release \
304 + ^topic/1 \
305 + ^topic/2 \
306 + main \
307 + HEAD &&
308 +
309 + cat >expect <<-\EOF &&
310 + The bundle contains these 2 refs:
311 + <COMMIT-P> refs/heads/main
312 + <COMMIT-P> HEAD
313 + The bundle requires these 2 refs:
314 + <COMMIT-M>
315 + <COMMIT-K>
316 + EOF
317 +
318 + git bundle verify 3.bdl |
319 + make_user_friendly_and_stable_output >actual &&
320 + test_i18ncmp expect actual &&
321 +
322 + test_bundle_object_count 3.bdl 4
323 +'
324 +
325 +test_expect_success 'create bundle 4 - with tags' '
326 + git bundle create 4.bdl \
327 + ^main \
328 + ^release \
329 + ^topic/1 \
330 + ^topic/2 \
331 + --all &&
332 +
333 + cat >expect <<-\EOF &&
334 + The bundle contains these 3 refs:
335 + <TAG-1> refs/tags/v1
336 + <TAG-2> refs/tags/v2
337 + <TAG-3> refs/tags/v3
338 + The bundle records a complete history.
339 + EOF
340 +
341 + git bundle verify 4.bdl |
342 + make_user_friendly_and_stable_output >actual &&
343 + test_i18ncmp expect actual &&
344 +
345 + test_bundle_object_count 4.bdl 3
346 +'
347 +
348 +test_expect_success 'clone from bundle' '
349 + git clone --mirror 1.bdl mirror.git &&
350 + git -C mirror.git show-ref |
351 + make_user_friendly_and_stable_output >actual &&
352 + cat >expect <<-\EOF &&
353 + <COMMIT-D> refs/heads/topic/1
354 + <COMMIT-H> refs/heads/topic/2
355 + EOF
356 + test_cmp expect actual &&
357 +
358 + git -C mirror.git fetch ../2.bdl "+refs/*:refs/*" &&
359 + git -C mirror.git show-ref |
360 + make_user_friendly_and_stable_output >actual &&
361 + cat >expect <<-\EOF &&
362 + <COMMIT-N> refs/heads/release
363 + <COMMIT-D> refs/heads/topic/1
364 + <COMMIT-H> refs/heads/topic/2
365 + EOF
366 + test_cmp expect actual &&
367 +
368 + git -C mirror.git fetch ../3.bdl "+refs/*:refs/*" &&
369 + git -C mirror.git show-ref |
370 + make_user_friendly_and_stable_output >actual &&
371 + cat >expect <<-\EOF &&
372 + <COMMIT-P> refs/heads/main
373 + <COMMIT-N> refs/heads/release
374 + <COMMIT-D> refs/heads/topic/1
375 + <COMMIT-H> refs/heads/topic/2
376 + EOF
377 + test_cmp expect actual &&
378 +
379 + git -C mirror.git fetch ../4.bdl "+refs/*:refs/*" &&
380 + git -C mirror.git show-ref |
381 + make_user_friendly_and_stable_output >actual &&
382 + cat >expect <<-\EOF &&
383 + <COMMIT-P> refs/heads/main
384 + <COMMIT-N> refs/heads/release
385 + <COMMIT-D> refs/heads/topic/1
386 + <COMMIT-H> refs/heads/topic/2
387 + <TAG-1> refs/tags/v1
388 + <TAG-2> refs/tags/v2
389 + <TAG-3> refs/tags/v3
390 + EOF
391 + test_cmp expect actual
392 +'
393 +
394 +test_done
t/test-bundle-functions.sh new
+42
@@ -0,0 +1,42 @@
1 +# Library of git-bundle related functions.
2 +
3 +# Display the pack data contained in the bundle file, bypassing the
4 +# header that contains the signature, prerequisites and references.
5 +convert_bundle_to_pack () {
6 + while read x && test -n "$x"
7 + do
8 + :;
9 + done
10 + cat
11 +}
12 +
13 +# Check count of objects in a bundle file.
14 +# We can use "--thin" opiton to check thin pack, which must be fixed by
15 +# command `git-index-pack --fix-thin --stdin`.
16 +test_bundle_object_count () {
17 + thin=
18 + if test "$1" = "--thin"
19 + then
20 + thin=t
21 + shift
22 + fi
23 + if test $# -ne 2
24 + then
25 + echo >&2 "args should be: <bundle> <count>"
26 + return 1
27 + fi
28 + bundle=$1
29 + pack=$bundle.pack
30 + convert_bundle_to_pack <"$bundle" >"$pack" &&
31 + if test -n "$thin"
32 + then
33 + mv "$pack" "$bundle.thin.pack" &&
34 + git index-pack --stdin --fix-thin "$pack" <"$bundle.thin.pack"
35 + else
36 + git index-pack "$pack"
37 + fi || return 1
38 + count=$(git show-index <"${pack%pack}idx" | wc -l) &&
39 + test $2 = $count && return 0
40 + echo >&2 "error: object count for $bundle is $count, not $2"
41 + return 1
42 +}