reftable/reader: introduce refcounting
[git/gitster.git] / t / t5323-pack-redundant.sh
blob8dbbcc5e51c06d7c5f56fcb3107860fcb66a5106
1 #!/bin/sh
3 # Copyright (c) 2018 Jiang Xin
6 test_description='Test git pack-redundant
8 In order to test git-pack-redundant, we will create a number of objects and
9 packs in the repository `main.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.
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
27 Another repository `shared.git` has unique objects (X-Z), while other objects
28 (marked with letter s) are shared through alt-odb (of `main.git`). The
29 relationship between packs and objects is as follows:
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
37 . ./test-lib.sh
39 main_repo=main.git
40 shared_repo=shared.git
42 git_pack_redundant='git pack-redundant --i-still-use-this'
44 # Create commits in <repo> and assign each commit's oid to shell variables
45 # given in the arguments (A, B, and C). E.g.:
47 # create_commits_in <repo> A B C
49 # NOTE: Avoid calling this function from a subshell since variable
50 # assignments will disappear when subshell exits.
51 create_commits_in () {
52 repo="$1" &&
53 if ! parent=$(git -C "$repo" rev-parse HEAD^{} 2>/dev/null)
54 then
55 parent=
56 fi &&
57 T=$(git -C "$repo" write-tree) &&
58 shift &&
59 while test $# -gt 0
61 name=$1 &&
62 test_tick &&
63 if test -z "$parent"
64 then
65 oid=$(echo $name | git -C "$repo" commit-tree $T)
66 else
67 oid=$(echo $name | git -C "$repo" commit-tree -p $parent $T)
68 fi &&
69 eval $name=$oid &&
70 parent=$oid &&
71 shift ||
72 return 1
73 done &&
74 git -C "$repo" update-ref refs/heads/main $oid
77 # Create pack in <repo> and assign pack id to variable given in the 2nd argument
78 # (<name>). Commits in the pack will be read from stdin. E.g.:
80 # create_pack_in <repo> <name> <<-EOF
81 # ...
82 # EOF
84 # NOTE: commits from stdin should be given using heredoc, not using pipe, and
85 # avoid calling this function from a subshell since variable assignments will
86 # disappear when subshell exits.
87 create_pack_in () {
88 repo="$1" &&
89 name="$2" &&
90 pack=$(git -C "$repo/objects/pack" pack-objects -q pack) &&
91 eval $name=$pack &&
92 eval P$pack=$name:$pack
95 format_packfiles () {
96 sed \
97 -e "s#.*/pack-\(.*\)\.idx#\1#" \
98 -e "s#.*/pack-\(.*\)\.pack#\1#" |
99 sort -u |
100 while read p
102 if test -z "$(eval echo \${P$p})"
103 then
104 echo $p
105 else
106 eval echo "\${P$p}"
108 done |
109 sort
112 test_expect_success 'setup main repo' '
113 git init --bare "$main_repo" &&
114 create_commits_in "$main_repo" A B C D E F G H I J K L M N O P Q R
117 test_expect_success 'main: pack-redundant works with no packfile' '
119 cd "$main_repo" &&
120 cat >expect <<-EOF &&
121 fatal: Zero packs found!
123 test_must_fail $git_pack_redundant --all >actual 2>&1 &&
124 test_cmp expect actual
128 #############################################################################
129 # Chart of packs and objects for this test case
131 # | T A B C D E F G H I J K L M N O P Q R
132 # ----+--------------------------------------
133 # P1 | x x x x x x x x
134 # ----+--------------------------------------
135 # ALL | x x x x x x x x
137 #############################################################################
138 test_expect_success 'main: pack-redundant works with one packfile' '
139 create_pack_in "$main_repo" P1 <<-EOF &&
150 cd "$main_repo" &&
151 $git_pack_redundant --all >out &&
152 test_must_be_empty out
156 #############################################################################
157 # Chart of packs and objects for this test case
159 # | T A B C D E F G H I J K L M N O P Q R
160 # ----+--------------------------------------
161 # P1 | x x x x x x x x
162 # P2 | x x x x x x x
163 # P3 | x x x x x x
164 # ----+--------------------------------------
165 # ALL | x x x x x x x x x x x x x x x
167 #############################################################################
168 test_expect_success 'main: no redundant for pack 1, 2, 3' '
169 create_pack_in "$main_repo" P2 <<-EOF &&
178 create_pack_in "$main_repo" P3 <<-EOF &&
187 cd "$main_repo" &&
188 $git_pack_redundant --all >out &&
189 test_must_be_empty out
193 #############################################################################
194 # Chart of packs and objects for this test case
196 # | T A B C D E F G H I J K L M N O P Q R
197 # ----+--------------------------------------
198 # P1 | x x x x x x x x
199 # P2 | x x x x x x x
200 # P3* | ! ! ! ! ! !
201 # P4 | x x x x x
202 # P5 | x x x x
203 # ----+--------------------------------------
204 # ALL | x x x x x x x x x x x x x x x x x x
206 #############################################################################
207 test_expect_success 'main: one of pack-2/pack-3 is redundant' '
208 create_pack_in "$main_repo" P4 <<-EOF &&
215 create_pack_in "$main_repo" P5 <<-EOF &&
222 cd "$main_repo" &&
223 cat >expect <<-EOF &&
224 P3:$P3
226 $git_pack_redundant --all >out &&
227 format_packfiles <out >actual &&
228 test_cmp expect actual
232 #############################################################################
233 # Chart of packs and objects for this test case
235 # | T A B C D E F G H I J K L M N O P Q R
236 # ----+--------------------------------------
237 # P1 | x x x x x x x x
238 # P2* | ! ! ! ! ! ! !
239 # P3 | x x x x x x
240 # P4* | ! ! ! ! !
241 # P5 | x x x x
242 # P6* | ! ! !
243 # P7 | x x
244 # ----+--------------------------------------
245 # ALL | x x x x x x x x x x x x x x x x x x x
247 #############################################################################
248 test_expect_success 'main: pack 2, 4, and 6 are redundant' '
249 create_pack_in "$main_repo" P6 <<-EOF &&
254 create_pack_in "$main_repo" P7 <<-EOF &&
259 cd "$main_repo" &&
260 cat >expect <<-EOF &&
261 P2:$P2
262 P4:$P4
263 P6:$P6
265 $git_pack_redundant --all >out &&
266 format_packfiles <out >actual &&
267 test_cmp expect actual
271 #############################################################################
272 # Chart of packs and objects for this test case
274 # | T A B C D E F G H I J K L M N O P Q R
275 # ----+--------------------------------------
276 # P1 | x x x x x x x x
277 # P2* | ! ! ! ! ! ! !
278 # P3 | x x x x x x
279 # P4* | ! ! ! ! !
280 # P5 | x x x x
281 # P6* | ! ! !
282 # P7 | x x
283 # P8* | !
284 # ----+--------------------------------------
285 # ALL | x x x x x x x x x x x x x x x x x x x
287 #############################################################################
288 test_expect_success 'main: pack-8 (subset of pack-1) is also redundant' '
289 create_pack_in "$main_repo" P8 <<-EOF &&
293 cd "$main_repo" &&
294 cat >expect <<-EOF &&
295 P2:$P2
296 P4:$P4
297 P6:$P6
298 P8:$P8
300 $git_pack_redundant --all >out &&
301 format_packfiles <out >actual &&
302 test_cmp expect actual
306 test_expect_success 'main: clean loose objects' '
308 cd "$main_repo" &&
309 git prune-packed &&
310 find objects -type f | sed -e "/objects\/pack\//d" >out &&
311 test_must_be_empty out
315 test_expect_success 'main: remove redundant packs and pass fsck' '
317 cd "$main_repo" &&
318 $git_pack_redundant --all | xargs rm &&
319 git fsck &&
320 $git_pack_redundant --all >out &&
321 test_must_be_empty out
325 # The following test cases will execute inside `shared.git`, instead of
326 # inside `main.git`.
327 test_expect_success 'setup shared.git' '
328 git clone --mirror "$main_repo" "$shared_repo" &&
330 cd "$shared_repo" &&
331 printf "../../$main_repo/objects\n" >objects/info/alternates
335 test_expect_success 'shared: all packs are redundant, but no output without --alt-odb' '
337 cd "$shared_repo" &&
338 $git_pack_redundant --all >out &&
339 test_must_be_empty out
343 #############################################################################
344 # Chart of packs and objects for this test case
346 # ================= main.git ================
347 # | T A B C D E F G H I J K L M N O P Q R <----------+
348 # ----+-------------------------------------- |
349 # P1 | x x x x x x x x |
350 # P3 | x x x x x x |
351 # P5 | x x x x |
352 # P7 | x x |
353 # ----+-------------------------------------- |
354 # ALL | x x x x x x x x x x x x x x x x x x x |
357 # ================ shared.git =============== |
358 # | T A B C D E F G H I J K L M N O P Q R <objects/info/alternates>
359 # ----+--------------------------------------
360 # P1* | s s s s s s s s
361 # P3* | s s s s s s
362 # P5* | s s s s
363 # P7* | s s
364 # ----+--------------------------------------
365 # ALL | x x x x x x x x x x x x x x x x x x x
367 #############################################################################
368 test_expect_success 'shared: show redundant packs in stderr for verbose mode' '
370 cd "$shared_repo" &&
371 cat >expect <<-EOF &&
372 P1:$P1
373 P3:$P3
374 P5:$P5
375 P7:$P7
377 $git_pack_redundant --all --verbose >out 2>out.err &&
378 test_must_be_empty out &&
379 grep "pack$" out.err | format_packfiles >actual &&
380 test_cmp expect actual
384 test_expect_success 'shared: remove redundant packs, no packs left' '
386 cd "$shared_repo" &&
387 cat >expect <<-EOF &&
388 fatal: Zero packs found!
390 $git_pack_redundant --all --alt-odb | xargs rm &&
391 git fsck &&
392 test_must_fail $git_pack_redundant --all --alt-odb >actual 2>&1 &&
393 test_cmp expect actual
397 test_expect_success 'shared: create new objects and packs' '
398 create_commits_in "$shared_repo" X Y Z &&
399 create_pack_in "$shared_repo" Px1 <<-EOF &&
407 create_pack_in "$shared_repo" Px2 <<-EOF
417 test_expect_success 'shared: no redundant without --alt-odb' '
419 cd "$shared_repo" &&
420 $git_pack_redundant --all >out &&
421 test_must_be_empty out
425 #############################################################################
426 # Chart of packs and objects for this test case
428 # ================= main.git ================
429 # | T A B C D E F G H I J K L M N O P Q R <----------------+
430 # ----+-------------------------------------- |
431 # P1 | x x x x x x x x |
432 # P3 | x x x x x x |
433 # P5 | x x x x |
434 # P7 | x x |
435 # ----+-------------------------------------- |
436 # ALL | x x x x x x x x x x x x x x x x x x x |
439 # ================ shared.git ======================= |
440 # | 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>
441 # ----+----------------------------------------------
442 # Px1 | s s s x x x
443 # Px2*| s s s ! ! !
444 # ----+----------------------------------------------
445 # ALL | s s s s s s s s s s s s s s s s s s s x x x
447 #############################################################################
448 test_expect_success 'shared: one pack is redundant with --alt-odb' '
450 cd "$shared_repo" &&
451 $git_pack_redundant --all --alt-odb >out &&
452 format_packfiles <out >actual &&
453 test_line_count = 1 actual
457 #############################################################################
458 # Chart of packs and objects for this test case
460 # ================= main.git ================
461 # | T A B C D E F G H I J K L M N O P Q R <----------------+
462 # ----+-------------------------------------- |
463 # P1 | x x x x x x x x |
464 # P3 | x x x x x x |
465 # P5 | x x x x |
466 # P7 | x x |
467 # ----+-------------------------------------- |
468 # ALL | x x x x x x x x x x x x x x x x x x x |
471 # ================ shared.git ======================= |
472 # | 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>
473 # ----+----------------------------------------------
474 # Px1*| s s s i i i
475 # Px2*| s s s i i i
476 # ----+----------------------------------------------
477 # ALL | s s s s s s s s s s s s s s s s s s s i i i
478 # (ignored objects, marked with i)
480 #############################################################################
481 test_expect_success 'shared: ignore unique objects and all two packs are redundant' '
483 cd "$shared_repo" &&
484 cat >expect <<-EOF &&
485 Px1:$Px1
486 Px2:$Px2
488 $git_pack_redundant --all --alt-odb >out <<-EOF &&
493 format_packfiles <out >actual &&
494 test_cmp expect actual
498 test_done