]>
Commit | Line | Data |
---|---|---|
3173a94d JX |
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 | |
0e37abd2 JX |
168 | # P2 | x x x x x x x |
169 | # P3* | ! ! ! ! ! ! | |
3173a94d JX |
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 | ############################################################################# | |
0e37abd2 | 176 | test_expect_success 'master: one of pack-2/pack-3 is redundant' ' |
3173a94d JX |
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 && | |
0e37abd2 | 193 | P3:$P3 |
3173a94d JX |
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 | ############################################################################# | |
0e37abd2 | 217 | test_expect_success 'master: pack 2, 4, and 6 are redundant' ' |
3173a94d JX |
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 | ############################################################################# | |
0e37abd2 | 257 | test_expect_success 'master: pack-8 (subset of pack-1) is also redundant' ' |
3173a94d JX |
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 | ||
0e37abd2 | 284 | test_expect_success 'master: remove redundant packs and pass fsck' ' |
3173a94d JX |
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 | ||
0e37abd2 | 304 | test_expect_success 'shared: all packs are redundant, but no output without --alt-odb' ' |
3173a94d JX |
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 | ############################################################################# | |
0e37abd2 | 337 | test_expect_success 'shared: show redundant packs in stderr for verbose mode' ' |
3173a94d JX |
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 |