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 ----+--------------------------------------
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 ----+----------------------------------------------
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 () {
53 if ! parent=$(git -C "$repo" rev-parse HEAD^{} 2>/dev/null)
57 T=$(git -C "$repo" write-tree) &&
65 oid=$(echo $name | git -C "$repo" commit-tree $T)
67 oid=$(echo $name | git -C "$repo" commit-tree -p $parent $T)
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
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.
90 pack=$(git -C "$repo/objects/pack" pack-objects -q pack) &&
92 eval P$pack=$name:$pack
97 -e "s#.*/pack-\(.*\)\.idx#\1#" \
98 -e "s#.*/pack-\(.*\)\.pack#\1#" |
102 if test -z "$(eval echo \${P$p})"
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 'master: pack-redundant works with no packfile' '
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 &&
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
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 &&
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
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 &&
223 cat >expect <<-EOF &&
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* | ! ! ! ! ! ! !
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 &&
260 cat >expect <<-EOF &&
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* | ! ! ! ! ! ! !
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 &&
294 cat >expect <<-EOF &&
300 $git_pack_redundant --all >out &&
301 format_packfiles <out >actual &&
302 test_cmp expect actual
306 test_expect_success 'main: clean loose objects' '
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' '
318 $git_pack_redundant --all | xargs rm &&
320 $git_pack_redundant --all >out &&
321 test_must_be_empty out
325 # The following test cases will execute inside `shared.git`, instead of
327 test_expect_success 'setup shared.git' '
328 git clone --mirror "$main_repo" "$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' '
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 |
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
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' '
371 cat >expect <<-EOF &&
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' '
387 cat >expect <<-EOF &&
388 fatal: Zero packs found!
390 $git_pack_redundant --all --alt-odb | xargs rm &&
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' '
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 |
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 # ----+----------------------------------------------
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' '
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 |
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 # ----+----------------------------------------------
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' '
484 cat >expect <<-EOF &&
488 $git_pack_redundant --all --alt-odb >out <<-EOF &&
493 format_packfiles <out >actual &&
494 test_cmp expect actual