]> git.ipfire.org Git - thirdparty/git.git/blob - t/t5323-pack-redundant.sh
Merge branch 'ug/doc-lose-dircache' into maint
[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 test_expect_success 'master: pack-redundant works with no packfile' '
116 (
117 cd "$master_repo" &&
118 cat >expect <<-EOF &&
119 fatal: Zero packs found!
120 EOF
121 test_must_fail git pack-redundant --all >actual 2>&1 &&
122 test_cmp expect actual
123 )
124 '
125
126 #############################################################################
127 # Chart of packs and objects for this test case
128 #
129 # | T A B C D E F G H I J K L M N O P Q R
130 # ----+--------------------------------------
131 # P1 | x x x x x x x x
132 # ----+--------------------------------------
133 # ALL | x x x x x x x x
134 #
135 #############################################################################
136 test_expect_success 'master: pack-redundant works with one packfile' '
137 create_pack_in "$master_repo" P1 <<-EOF &&
138 $T
139 $A
140 $B
141 $C
142 $D
143 $E
144 $F
145 $R
146 EOF
147 (
148 cd "$master_repo" &&
149 git pack-redundant --all >out &&
150 test_must_be_empty out
151 )
152 '
153
154 #############################################################################
155 # Chart of packs and objects for this test case
156 #
157 # | T A B C D E F G H I J K L M N O P Q R
158 # ----+--------------------------------------
159 # P1 | x x x x x x x x
160 # P2 | x x x x x x x
161 # P3 | x x x x x x
162 # ----+--------------------------------------
163 # ALL | x x x x x x x x x x x x x x x
164 #
165 #############################################################################
166 test_expect_success 'master: no redundant for pack 1, 2, 3' '
167 create_pack_in "$master_repo" P2 <<-EOF &&
168 $B
169 $C
170 $D
171 $E
172 $G
173 $H
174 $I
175 EOF
176 create_pack_in "$master_repo" P3 <<-EOF &&
177 $F
178 $I
179 $J
180 $K
181 $L
182 $M
183 EOF
184 (
185 cd "$master_repo" &&
186 git pack-redundant --all >out &&
187 test_must_be_empty out
188 )
189 '
190
191 #############################################################################
192 # Chart of packs and objects for this test case
193 #
194 # | T A B C D E F G H I J K L M N O P Q R
195 # ----+--------------------------------------
196 # P1 | x x x x x x x x
197 # P2 | x x x x x x x
198 # P3* | ! ! ! ! ! !
199 # P4 | x x x x x
200 # P5 | x x x x
201 # ----+--------------------------------------
202 # ALL | x x x x x x x x x x x x x x x x x x
203 #
204 #############################################################################
205 test_expect_success 'master: one of pack-2/pack-3 is redundant' '
206 create_pack_in "$master_repo" P4 <<-EOF &&
207 $J
208 $K
209 $L
210 $M
211 $P
212 EOF
213 create_pack_in "$master_repo" P5 <<-EOF &&
214 $G
215 $H
216 $N
217 $O
218 EOF
219 (
220 cd "$master_repo" &&
221 cat >expect <<-EOF &&
222 P3:$P3
223 EOF
224 git pack-redundant --all >out &&
225 format_packfiles <out >actual &&
226 test_cmp expect actual
227 )
228 '
229
230 #############################################################################
231 # Chart of packs and objects for this test case
232 #
233 # | T A B C D E F G H I J K L M N O P Q R
234 # ----+--------------------------------------
235 # P1 | x x x x x x x x
236 # P2* | ! ! ! ! ! ! !
237 # P3 | x x x x x x
238 # P4* | ! ! ! ! !
239 # P5 | x x x x
240 # P6* | ! ! !
241 # P7 | x x
242 # ----+--------------------------------------
243 # ALL | x x x x x x x x x x x x x x x x x x x
244 #
245 #############################################################################
246 test_expect_success 'master: pack 2, 4, and 6 are redundant' '
247 create_pack_in "$master_repo" P6 <<-EOF &&
248 $N
249 $O
250 $Q
251 EOF
252 create_pack_in "$master_repo" P7 <<-EOF &&
253 $P
254 $Q
255 EOF
256 (
257 cd "$master_repo" &&
258 cat >expect <<-EOF &&
259 P2:$P2
260 P4:$P4
261 P6:$P6
262 EOF
263 git pack-redundant --all >out &&
264 format_packfiles <out >actual &&
265 test_cmp expect actual
266 )
267 '
268
269 #############################################################################
270 # Chart of packs and objects for this test case
271 #
272 # | T A B C D E F G H I J K L M N O P Q R
273 # ----+--------------------------------------
274 # P1 | x x x x x x x x
275 # P2* | ! ! ! ! ! ! !
276 # P3 | x x x x x x
277 # P4* | ! ! ! ! !
278 # P5 | x x x x
279 # P6* | ! ! !
280 # P7 | x x
281 # P8* | !
282 # ----+--------------------------------------
283 # ALL | x x x x x x x x x x x x x x x x x x x
284 #
285 #############################################################################
286 test_expect_success 'master: pack-8 (subset of pack-1) is also redundant' '
287 create_pack_in "$master_repo" P8 <<-EOF &&
288 $A
289 EOF
290 (
291 cd "$master_repo" &&
292 cat >expect <<-EOF &&
293 P2:$P2
294 P4:$P4
295 P6:$P6
296 P8:$P8
297 EOF
298 git pack-redundant --all >out &&
299 format_packfiles <out >actual &&
300 test_cmp expect actual
301 )
302 '
303
304 test_expect_success 'master: clean loose objects' '
305 (
306 cd "$master_repo" &&
307 git prune-packed &&
308 find objects -type f | sed -e "/objects\/pack\//d" >out &&
309 test_must_be_empty out
310 )
311 '
312
313 test_expect_success 'master: remove redundant packs and pass fsck' '
314 (
315 cd "$master_repo" &&
316 git pack-redundant --all | xargs rm &&
317 git fsck &&
318 git pack-redundant --all >out &&
319 test_must_be_empty out
320 )
321 '
322
323 # The following test cases will execute inside `shared.git`, instead of
324 # inside `master.git`.
325 test_expect_success 'setup shared.git' '
326 git clone --mirror "$master_repo" "$shared_repo" &&
327 (
328 cd "$shared_repo" &&
329 printf "../../$master_repo/objects\n" >objects/info/alternates
330 )
331 '
332
333 test_expect_success 'shared: all packs are redundant, but no output without --alt-odb' '
334 (
335 cd "$shared_repo" &&
336 git pack-redundant --all >out &&
337 test_must_be_empty out
338 )
339 '
340
341 #############################################################################
342 # Chart of packs and objects for this test case
343 #
344 # ================ master.git ===============
345 # | T A B C D E F G H I J K L M N O P Q R <----------+
346 # ----+-------------------------------------- |
347 # P1 | x x x x x x x x |
348 # P3 | x x x x x x |
349 # P5 | x x x x |
350 # P7 | x x |
351 # ----+-------------------------------------- |
352 # ALL | x x x x x x x x x x x x x x x x x x x |
353 # |
354 # |
355 # ================ shared.git =============== |
356 # | T A B C D E F G H I J K L M N O P Q R <objects/info/alternates>
357 # ----+--------------------------------------
358 # P1* | s s s s s s s s
359 # P3* | s s s s s s
360 # P5* | s s s s
361 # P7* | s s
362 # ----+--------------------------------------
363 # ALL | x x x x x x x x x x x x x x x x x x x
364 #
365 #############################################################################
366 test_expect_success 'shared: show redundant packs in stderr for verbose mode' '
367 (
368 cd "$shared_repo" &&
369 cat >expect <<-EOF &&
370 P1:$P1
371 P3:$P3
372 P5:$P5
373 P7:$P7
374 EOF
375 git pack-redundant --all --verbose >out 2>out.err &&
376 test_must_be_empty out &&
377 grep "pack$" out.err | format_packfiles >actual &&
378 test_cmp expect actual
379 )
380 '
381
382 test_expect_success 'shared: remove redundant packs, no packs left' '
383 (
384 cd "$shared_repo" &&
385 cat >expect <<-EOF &&
386 fatal: Zero packs found!
387 EOF
388 git pack-redundant --all --alt-odb | xargs rm &&
389 git fsck &&
390 test_must_fail git pack-redundant --all --alt-odb >actual 2>&1 &&
391 test_cmp expect actual
392 )
393 '
394
395 test_expect_success 'shared: create new objects and packs' '
396 create_commits_in "$shared_repo" X Y Z &&
397 create_pack_in "$shared_repo" Px1 <<-EOF &&
398 $X
399 $Y
400 $Z
401 $A
402 $B
403 $C
404 EOF
405 create_pack_in "$shared_repo" Px2 <<-EOF
406 $X
407 $Y
408 $Z
409 $D
410 $E
411 $F
412 EOF
413 '
414
415 test_expect_success 'shared: no redundant without --alt-odb' '
416 (
417 cd "$shared_repo" &&
418 git pack-redundant --all >out &&
419 test_must_be_empty out
420 )
421 '
422
423 #############################################################################
424 # Chart of packs and objects for this test case
425 #
426 # ================ master.git ===============
427 # | T A B C D E F G H I J K L M N O P Q R <----------------+
428 # ----+-------------------------------------- |
429 # P1 | x x x x x x x x |
430 # P3 | x x x x x x |
431 # P5 | x x x x |
432 # P7 | x x |
433 # ----+-------------------------------------- |
434 # ALL | x x x x x x x x x x x x x x x x x x x |
435 # |
436 # |
437 # ================ shared.git ======================= |
438 # | 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>
439 # ----+----------------------------------------------
440 # Px1 | s s s x x x
441 # Px2*| s s s ! ! !
442 # ----+----------------------------------------------
443 # ALL | s s s s s s s s s s s s s s s s s s s x x x
444 #
445 #############################################################################
446 test_expect_success 'shared: one pack is redundant with --alt-odb' '
447 (
448 cd "$shared_repo" &&
449 git pack-redundant --all --alt-odb >out &&
450 format_packfiles <out >actual &&
451 test_line_count = 1 actual
452 )
453 '
454
455 #############################################################################
456 # Chart of packs and objects for this test case
457 #
458 # ================ master.git ===============
459 # | T A B C D E F G H I J K L M N O P Q R <----------------+
460 # ----+-------------------------------------- |
461 # P1 | x x x x x x x x |
462 # P3 | x x x x x x |
463 # P5 | x x x x |
464 # P7 | x x |
465 # ----+-------------------------------------- |
466 # ALL | x x x x x x x x x x x x x x x x x x x |
467 # |
468 # |
469 # ================ shared.git ======================= |
470 # | 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>
471 # ----+----------------------------------------------
472 # Px1*| s s s i i i
473 # Px2*| s s s i i i
474 # ----+----------------------------------------------
475 # ALL | s s s s s s s s s s s s s s s s s s s i i i
476 # (ignored objects, marked with i)
477 #
478 #############################################################################
479 test_expect_success 'shared: ignore unique objects and all two packs are redundant' '
480 (
481 cd "$shared_repo" &&
482 cat >expect <<-EOF &&
483 Px1:$Px1
484 Px2:$Px2
485 EOF
486 git pack-redundant --all --alt-odb >out <<-EOF &&
487 $X
488 $Y
489 $Z
490 EOF
491 format_packfiles <out >actual &&
492 test_cmp expect actual
493 )
494 '
495
496 test_done