]> git.ipfire.org Git - thirdparty/git.git/blob - t/t5323-pack-redundant.sh
The sixth batch
[thirdparty/git.git] / t / t5323-pack-redundant.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2018 Jiang Xin
4 #
5
6 test_description='Test git pack-redundant
7
8 In order to test git-pack-redundant, we will create a number of objects and
9 packs in the repository `master.git`. The relationship between packs (P1-P8)
10 and objects (T, A-R) is showed in the following chart. Objects of a pack will
11 be marked with letter x, while objects of redundant packs will be marked with
12 exclamation point, and redundant pack itself will be marked with asterisk.
13
14 | T A B C D E F G H I J K L M N O P Q R
15 ----+--------------------------------------
16 P1 | x x x x x x x x
17 P2* | ! ! ! ! ! ! !
18 P3 | x x x x x x
19 P4* | ! ! ! ! !
20 P5 | x x x x
21 P6* | ! ! !
22 P7 | x x
23 P8* | !
24 ----+--------------------------------------
25 ALL | x x x x x x x x x x x x x x x x x x x
26
27 Another repository `shared.git` has unique objects (X-Z), while other objects
28 (marked with letter s) are shared through alt-odb (of `master.git`). The
29 relationship between packs and objects is as follows:
30
31 | T A B C D E F G H I J K L M N O P Q R X Y Z
32 ----+----------------------------------------------
33 Px1 | s s s x x x
34 Px2 | s s s x x x
35 '
36
37 . ./test-lib.sh
38
39 master_repo=master.git
40 shared_repo=shared.git
41
42 # Create commits in <repo> and assign each commit's oid to shell variables
43 # given in the arguments (A, B, and C). E.g.:
44 #
45 # create_commits_in <repo> A B C
46 #
47 # NOTE: Avoid calling this function from a subshell since variable
48 # assignments will disappear when subshell exits.
49 create_commits_in () {
50 repo="$1" &&
51 if ! parent=$(git -C "$repo" rev-parse HEAD^{} 2>/dev/null)
52 then
53 parent=
54 fi &&
55 T=$(git -C "$repo" write-tree) &&
56 shift &&
57 while test $# -gt 0
58 do
59 name=$1 &&
60 test_tick &&
61 if test -z "$parent"
62 then
63 oid=$(echo $name | git -C "$repo" commit-tree $T)
64 else
65 oid=$(echo $name | git -C "$repo" commit-tree -p $parent $T)
66 fi &&
67 eval $name=$oid &&
68 parent=$oid &&
69 shift ||
70 return 1
71 done &&
72 git -C "$repo" update-ref refs/heads/master $oid
73 }
74
75 # Create pack in <repo> and assign pack id to variable given in the 2nd argument
76 # (<name>). Commits in the pack will be read from stdin. E.g.:
77 #
78 # create_pack_in <repo> <name> <<-EOF
79 # ...
80 # EOF
81 #
82 # NOTE: commits from stdin should be given using heredoc, not using pipe, and
83 # avoid calling this function from a subshell since variable assignments will
84 # disappear when subshell exits.
85 create_pack_in () {
86 repo="$1" &&
87 name="$2" &&
88 pack=$(git -C "$repo/objects/pack" pack-objects -q pack) &&
89 eval $name=$pack &&
90 eval P$pack=$name:$pack
91 }
92
93 format_packfiles () {
94 sed \
95 -e "s#.*/pack-\(.*\)\.idx#\1#" \
96 -e "s#.*/pack-\(.*\)\.pack#\1#" |
97 sort -u |
98 while read p
99 do
100 if test -z "$(eval echo \${P$p})"
101 then
102 echo $p
103 else
104 eval echo "\${P$p}"
105 fi
106 done |
107 sort
108 }
109
110 test_expect_success 'setup master repo' '
111 git init --bare "$master_repo" &&
112 create_commits_in "$master_repo" A B C D E F G H I J K L M N O P Q R
113 '
114
115 #############################################################################
116 # Chart of packs and objects for this test case
117 #
118 # | T A B C D E F G H I J K L M N O P Q R
119 # ----+--------------------------------------
120 # P1 | x x x x x x x x
121 # P2 | x x x x x x x
122 # P3 | x x x x x x
123 # ----+--------------------------------------
124 # ALL | x x x x x x x x x x x x x x x
125 #
126 #############################################################################
127 test_expect_success 'master: no redundant for pack 1, 2, 3' '
128 create_pack_in "$master_repo" P1 <<-EOF &&
129 $T
130 $A
131 $B
132 $C
133 $D
134 $E
135 $F
136 $R
137 EOF
138 create_pack_in "$master_repo" P2 <<-EOF &&
139 $B
140 $C
141 $D
142 $E
143 $G
144 $H
145 $I
146 EOF
147 create_pack_in "$master_repo" P3 <<-EOF &&
148 $F
149 $I
150 $J
151 $K
152 $L
153 $M
154 EOF
155 (
156 cd "$master_repo" &&
157 git pack-redundant --all >out &&
158 test_must_be_empty out
159 )
160 '
161
162 #############################################################################
163 # Chart of packs and objects for this test case
164 #
165 # | T A B C D E F G H I J K L M N O P Q R
166 # ----+--------------------------------------
167 # P1 | x x x x x x x x
168 # P2 | x x x x x x x
169 # P3* | ! ! ! ! ! !
170 # P4 | x x x x x
171 # P5 | x x x x
172 # ----+--------------------------------------
173 # ALL | x x x x x x x x x x x x x x x x x x
174 #
175 #############################################################################
176 test_expect_success 'master: one of pack-2/pack-3 is redundant' '
177 create_pack_in "$master_repo" P4 <<-EOF &&
178 $J
179 $K
180 $L
181 $M
182 $P
183 EOF
184 create_pack_in "$master_repo" P5 <<-EOF &&
185 $G
186 $H
187 $N
188 $O
189 EOF
190 (
191 cd "$master_repo" &&
192 cat >expect <<-EOF &&
193 P3:$P3
194 EOF
195 git pack-redundant --all >out &&
196 format_packfiles <out >actual &&
197 test_cmp expect actual
198 )
199 '
200
201 #############################################################################
202 # Chart of packs and objects for this test case
203 #
204 # | T A B C D E F G H I J K L M N O P Q R
205 # ----+--------------------------------------
206 # P1 | x x x x x x x x
207 # P2* | ! ! ! ! ! ! !
208 # P3 | x x x x x x
209 # P4* | ! ! ! ! !
210 # P5 | x x x x
211 # P6* | ! ! !
212 # P7 | x x
213 # ----+--------------------------------------
214 # ALL | x x x x x x x x x x x x x x x x x x x
215 #
216 #############################################################################
217 test_expect_success 'master: pack 2, 4, and 6 are redundant' '
218 create_pack_in "$master_repo" P6 <<-EOF &&
219 $N
220 $O
221 $Q
222 EOF
223 create_pack_in "$master_repo" P7 <<-EOF &&
224 $P
225 $Q
226 EOF
227 (
228 cd "$master_repo" &&
229 cat >expect <<-EOF &&
230 P2:$P2
231 P4:$P4
232 P6:$P6
233 EOF
234 git pack-redundant --all >out &&
235 format_packfiles <out >actual &&
236 test_cmp expect actual
237 )
238 '
239
240 #############################################################################
241 # Chart of packs and objects for this test case
242 #
243 # | T A B C D E F G H I J K L M N O P Q R
244 # ----+--------------------------------------
245 # P1 | x x x x x x x x
246 # P2* | ! ! ! ! ! ! !
247 # P3 | x x x x x x
248 # P4* | ! ! ! ! !
249 # P5 | x x x x
250 # P6* | ! ! !
251 # P7 | x x
252 # P8* | !
253 # ----+--------------------------------------
254 # ALL | x x x x x x x x x x x x x x x x x x x
255 #
256 #############################################################################
257 test_expect_success 'master: pack-8 (subset of pack-1) is also redundant' '
258 create_pack_in "$master_repo" P8 <<-EOF &&
259 $A
260 EOF
261 (
262 cd "$master_repo" &&
263 cat >expect <<-EOF &&
264 P2:$P2
265 P4:$P4
266 P6:$P6
267 P8:$P8
268 EOF
269 git pack-redundant --all >out &&
270 format_packfiles <out >actual &&
271 test_cmp expect actual
272 )
273 '
274
275 test_expect_success 'master: clean loose objects' '
276 (
277 cd "$master_repo" &&
278 git prune-packed &&
279 find objects -type f | sed -e "/objects\/pack\//d" >out &&
280 test_must_be_empty out
281 )
282 '
283
284 test_expect_success 'master: remove redundant packs and pass fsck' '
285 (
286 cd "$master_repo" &&
287 git pack-redundant --all | xargs rm &&
288 git fsck &&
289 git pack-redundant --all >out &&
290 test_must_be_empty out
291 )
292 '
293
294 # The following test cases will execute inside `shared.git`, instead of
295 # inside `master.git`.
296 test_expect_success 'setup shared.git' '
297 git clone --mirror "$master_repo" "$shared_repo" &&
298 (
299 cd "$shared_repo" &&
300 printf "../../$master_repo/objects\n" >objects/info/alternates
301 )
302 '
303
304 test_expect_success 'shared: all packs are redundant, but no output without --alt-odb' '
305 (
306 cd "$shared_repo" &&
307 git pack-redundant --all >out &&
308 test_must_be_empty out
309 )
310 '
311
312 #############################################################################
313 # Chart of packs and objects for this test case
314 #
315 # ================ master.git ===============
316 # | T A B C D E F G H I J K L M N O P Q R <----------+
317 # ----+-------------------------------------- |
318 # P1 | x x x x x x x x |
319 # P3 | x x x x x x |
320 # P5 | x x x x |
321 # P7 | x x |
322 # ----+-------------------------------------- |
323 # ALL | x x x x x x x x x x x x x x x x x x x |
324 # |
325 # |
326 # ================ shared.git =============== |
327 # | T A B C D E F G H I J K L M N O P Q R <objects/info/alternates>
328 # ----+--------------------------------------
329 # P1* | s s s s s s s s
330 # P3* | s s s s s s
331 # P5* | s s s s
332 # P7* | s s
333 # ----+--------------------------------------
334 # ALL | x x x x x x x x x x x x x x x x x x x
335 #
336 #############################################################################
337 test_expect_success 'shared: show redundant packs in stderr for verbose mode' '
338 (
339 cd "$shared_repo" &&
340 cat >expect <<-EOF &&
341 P1:$P1
342 P3:$P3
343 P5:$P5
344 P7:$P7
345 EOF
346 git pack-redundant --all --verbose >out 2>out.err &&
347 test_must_be_empty out &&
348 grep "pack$" out.err | format_packfiles >actual &&
349 test_cmp expect actual
350 )
351 '
352
353 test_expect_success 'shared: remove redundant packs, no packs left' '
354 (
355 cd "$shared_repo" &&
356 cat >expect <<-EOF &&
357 fatal: Zero packs found!
358 EOF
359 git pack-redundant --all --alt-odb | xargs rm &&
360 git fsck &&
361 test_must_fail git pack-redundant --all --alt-odb >actual 2>&1 &&
362 test_cmp expect actual
363 )
364 '
365
366 test_expect_success 'shared: create new objects and packs' '
367 create_commits_in "$shared_repo" X Y Z &&
368 create_pack_in "$shared_repo" Px1 <<-EOF &&
369 $X
370 $Y
371 $Z
372 $A
373 $B
374 $C
375 EOF
376 create_pack_in "$shared_repo" Px2 <<-EOF
377 $X
378 $Y
379 $Z
380 $D
381 $E
382 $F
383 EOF
384 '
385
386 test_expect_success 'shared: no redundant without --alt-odb' '
387 (
388 cd "$shared_repo" &&
389 git pack-redundant --all >out &&
390 test_must_be_empty out
391 )
392 '
393
394 #############################################################################
395 # Chart of packs and objects for this test case
396 #
397 # ================ master.git ===============
398 # | T A B C D E F G H I J K L M N O P Q R <----------------+
399 # ----+-------------------------------------- |
400 # P1 | x x x x x x x x |
401 # P3 | x x x x x x |
402 # P5 | x x x x |
403 # P7 | x x |
404 # ----+-------------------------------------- |
405 # ALL | x x x x x x x x x x x x x x x x x x x |
406 # |
407 # |
408 # ================ shared.git ======================= |
409 # | T A B C D E F G H I J K L M N O P Q R X Y Z <objects/info/alternates>
410 # ----+----------------------------------------------
411 # Px1 | s s s x x x
412 # Px2*| s s s ! ! !
413 # ----+----------------------------------------------
414 # ALL | s s s s s s s s s s s s s s s s s s s x x x
415 #
416 #############################################################################
417 test_expect_success 'shared: one pack is redundant with --alt-odb' '
418 (
419 cd "$shared_repo" &&
420 git pack-redundant --all --alt-odb >out &&
421 format_packfiles <out >actual &&
422 test_line_count = 1 actual
423 )
424 '
425
426 #############################################################################
427 # Chart of packs and objects for this test case
428 #
429 # ================ master.git ===============
430 # | T A B C D E F G H I J K L M N O P Q R <----------------+
431 # ----+-------------------------------------- |
432 # P1 | x x x x x x x x |
433 # P3 | x x x x x x |
434 # P5 | x x x x |
435 # P7 | x x |
436 # ----+-------------------------------------- |
437 # ALL | x x x x x x x x x x x x x x x x x x x |
438 # |
439 # |
440 # ================ shared.git ======================= |
441 # | T A B C D E F G H I J K L M N O P Q R X Y Z <objects/info/alternates>
442 # ----+----------------------------------------------
443 # Px1*| s s s i i i
444 # Px2*| s s s i i i
445 # ----+----------------------------------------------
446 # ALL | s s s s s s s s s s s s s s s s s s s i i i
447 # (ignored objects, marked with i)
448 #
449 #############################################################################
450 test_expect_success 'shared: ignore unique objects and all two packs are redundant' '
451 (
452 cd "$shared_repo" &&
453 cat >expect <<-EOF &&
454 Px1:$Px1
455 Px2:$Px2
456 EOF
457 git pack-redundant --all --alt-odb >out <<-EOF &&
458 $X
459 $Y
460 $Z
461 EOF
462 format_packfiles <out >actual &&
463 test_cmp expect actual
464 )
465 '
466
467 test_done