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
+}