]>
Commit | Line | Data |
---|---|---|
b7573536 TB |
1 | #!/bin/sh |
2 | ||
3 | test_description='cruft pack related pack-objects tests' | |
4 | . ./test-lib.sh | |
5 | ||
6 | objdir=.git/objects | |
7 | packdir=$objdir/pack | |
8 | ||
9 | basic_cruft_pack_tests () { | |
10 | expire="$1" | |
11 | ||
12 | test_expect_success "unreachable loose objects are packed (expire $expire)" ' | |
13 | git init repo && | |
14 | test_when_finished "rm -fr repo" && | |
15 | ( | |
16 | cd repo && | |
17 | ||
18 | test_commit base && | |
19 | git repack -Ad && | |
20 | test_commit loose && | |
21 | ||
22 | test-tool chmtime +2000 "$objdir/$(test_oid_to_path \ | |
23 | $(git rev-parse loose:loose.t))" && | |
24 | test-tool chmtime +1000 "$objdir/$(test_oid_to_path \ | |
25 | $(git rev-parse loose^{tree}))" && | |
26 | ||
27 | ( | |
28 | git rev-list --objects --no-object-names base..loose | | |
29 | while read oid | |
30 | do | |
31 | path="$objdir/$(test_oid_to_path "$oid")" && | |
32 | printf "%s %d\n" "$oid" "$(test-tool chmtime --get "$path")" | |
33 | done | | |
34 | sort -k1 | |
35 | ) >expect && | |
36 | ||
37 | keep="$(basename "$(ls $packdir/pack-*.pack)")" && | |
38 | cruft="$(echo $keep | git pack-objects --cruft \ | |
39 | --cruft-expiration="$expire" $packdir/pack)" && | |
40 | test-tool pack-mtimes "pack-$cruft.mtimes" >actual && | |
41 | ||
42 | test_cmp expect actual | |
43 | ) | |
44 | ' | |
45 | ||
46 | test_expect_success "unreachable packed objects are packed (expire $expire)" ' | |
47 | git init repo && | |
48 | test_when_finished "rm -fr repo" && | |
49 | ( | |
50 | cd repo && | |
51 | ||
52 | test_commit packed && | |
53 | git repack -Ad && | |
54 | test_commit other && | |
55 | ||
56 | git rev-list --objects --no-object-names packed.. >objects && | |
57 | keep="$(basename "$(ls $packdir/pack-*.pack)")" && | |
58 | other="$(git pack-objects --delta-base-offset \ | |
59 | $packdir/pack <objects)" && | |
60 | git prune-packed && | |
61 | ||
62 | test-tool chmtime --get -100 "$packdir/pack-$other.pack" >expect && | |
63 | ||
64 | cruft="$(git pack-objects --cruft --cruft-expiration="$expire" $packdir/pack <<-EOF | |
65 | $keep | |
66 | -pack-$other.pack | |
67 | EOF | |
68 | )" && | |
69 | test-tool pack-mtimes "pack-$cruft.mtimes" >actual.raw && | |
70 | ||
71 | cut -d" " -f2 <actual.raw | sort -u >actual && | |
72 | ||
73 | test_cmp expect actual | |
74 | ) | |
75 | ' | |
76 | ||
77 | test_expect_success "unreachable cruft objects are repacked (expire $expire)" ' | |
78 | git init repo && | |
79 | test_when_finished "rm -fr repo" && | |
80 | ( | |
81 | cd repo && | |
82 | ||
83 | test_commit packed && | |
84 | git repack -Ad && | |
85 | test_commit other && | |
86 | ||
87 | git rev-list --objects --no-object-names packed.. >objects && | |
88 | keep="$(basename "$(ls $packdir/pack-*.pack)")" && | |
89 | ||
90 | cruft_a="$(echo $keep | git pack-objects --cruft --cruft-expiration="$expire" $packdir/pack)" && | |
91 | git prune-packed && | |
92 | cruft_b="$(git pack-objects --cruft --cruft-expiration="$expire" $packdir/pack <<-EOF | |
93 | $keep | |
94 | -pack-$cruft_a.pack | |
95 | EOF | |
96 | )" && | |
97 | ||
98 | test-tool pack-mtimes "pack-$cruft_a.mtimes" >expect.raw && | |
99 | test-tool pack-mtimes "pack-$cruft_b.mtimes" >actual.raw && | |
100 | ||
101 | sort <expect.raw >expect && | |
102 | sort <actual.raw >actual && | |
103 | ||
104 | test_cmp expect actual | |
105 | ) | |
106 | ' | |
107 | ||
108 | test_expect_success "multiple cruft packs (expire $expire)" ' | |
109 | git init repo && | |
110 | test_when_finished "rm -fr repo" && | |
111 | ( | |
112 | cd repo && | |
113 | ||
114 | test_commit reachable && | |
115 | git repack -Ad && | |
116 | keep="$(basename "$(ls $packdir/pack-*.pack)")" && | |
117 | ||
118 | test_commit cruft && | |
119 | loose="$objdir/$(test_oid_to_path $(git rev-parse cruft))" && | |
120 | ||
121 | # generate three copies of the cruft object in different | |
122 | # cruft packs, each with a unique mtime: | |
123 | # - one expired (1000 seconds ago) | |
124 | # - two non-expired (one 1000 seconds in the future, | |
125 | # one 1500 seconds in the future) | |
126 | test-tool chmtime =-1000 "$loose" && | |
127 | git pack-objects --cruft $packdir/pack-A <<-EOF && | |
128 | $keep | |
129 | EOF | |
130 | test-tool chmtime =+1000 "$loose" && | |
131 | git pack-objects --cruft $packdir/pack-B <<-EOF && | |
132 | $keep | |
133 | -$(basename $(ls $packdir/pack-A-*.pack)) | |
134 | EOF | |
135 | test-tool chmtime =+1500 "$loose" && | |
136 | git pack-objects --cruft $packdir/pack-C <<-EOF && | |
137 | $keep | |
138 | -$(basename $(ls $packdir/pack-A-*.pack)) | |
139 | -$(basename $(ls $packdir/pack-B-*.pack)) | |
140 | EOF | |
141 | ||
142 | # ensure the resulting cruft pack takes the most recent | |
143 | # mtime among all copies | |
144 | cruft="$(git pack-objects --cruft \ | |
145 | --cruft-expiration="$expire" \ | |
146 | $packdir/pack <<-EOF | |
147 | $keep | |
148 | -$(basename $(ls $packdir/pack-A-*.pack)) | |
149 | -$(basename $(ls $packdir/pack-B-*.pack)) | |
150 | -$(basename $(ls $packdir/pack-C-*.pack)) | |
151 | EOF | |
152 | )" && | |
153 | ||
154 | test-tool pack-mtimes "$(basename $(ls $packdir/pack-C-*.mtimes))" >expect.raw && | |
155 | test-tool pack-mtimes "pack-$cruft.mtimes" >actual.raw && | |
156 | ||
157 | sort expect.raw >expect && | |
158 | sort actual.raw >actual && | |
159 | test_cmp expect actual | |
160 | ) | |
161 | ' | |
162 | ||
163 | test_expect_success "cruft packs tolerate missing trees (expire $expire)" ' | |
164 | git init repo && | |
165 | test_when_finished "rm -fr repo" && | |
166 | ( | |
167 | cd repo && | |
168 | ||
169 | test_commit reachable && | |
170 | test_commit cruft && | |
171 | ||
172 | tree="$(git rev-parse cruft^{tree})" && | |
173 | ||
174 | git reset --hard reachable && | |
175 | git tag -d cruft && | |
176 | git reflog expire --all --expire=all && | |
177 | ||
178 | # remove the unreachable tree, but leave the commit | |
179 | # which has it as its root tree intact | |
180 | rm -fr "$objdir/$(test_oid_to_path "$tree")" && | |
181 | ||
182 | git repack -Ad && | |
183 | basename $(ls $packdir/pack-*.pack) >in && | |
184 | git pack-objects --cruft --cruft-expiration="$expire" \ | |
185 | $packdir/pack <in | |
186 | ) | |
187 | ' | |
188 | ||
189 | test_expect_success "cruft packs tolerate missing blobs (expire $expire)" ' | |
190 | git init repo && | |
191 | test_when_finished "rm -fr repo" && | |
192 | ( | |
193 | cd repo && | |
194 | ||
195 | test_commit reachable && | |
196 | test_commit cruft && | |
197 | ||
198 | blob="$(git rev-parse cruft:cruft.t)" && | |
199 | ||
200 | git reset --hard reachable && | |
201 | git tag -d cruft && | |
202 | git reflog expire --all --expire=all && | |
203 | ||
204 | # remove the unreachable blob, but leave the commit (and | |
205 | # the root tree of that commit) intact | |
206 | rm -fr "$objdir/$(test_oid_to_path "$blob")" && | |
207 | ||
208 | git repack -Ad && | |
209 | basename $(ls $packdir/pack-*.pack) >in && | |
210 | git pack-objects --cruft --cruft-expiration="$expire" \ | |
211 | $packdir/pack <in | |
212 | ) | |
213 | ' | |
214 | } | |
215 | ||
216 | basic_cruft_pack_tests never | |
a7d49383 TB |
217 | basic_cruft_pack_tests 2.weeks.ago |
218 | ||
219 | test_expect_success 'cruft tags rescue tagged objects' ' | |
220 | git init repo && | |
221 | test_when_finished "rm -fr repo" && | |
222 | ( | |
223 | cd repo && | |
224 | ||
225 | test_commit packed && | |
226 | git repack -Ad && | |
227 | ||
228 | test_commit tagged && | |
229 | git tag -a annotated -m tag && | |
230 | ||
231 | git rev-list --objects --no-object-names packed.. >objects && | |
232 | while read oid | |
233 | do | |
234 | test-tool chmtime -1000 \ | |
235 | "$objdir/$(test_oid_to_path $oid)" | |
236 | done <objects && | |
237 | ||
238 | test-tool chmtime -500 \ | |
239 | "$objdir/$(test_oid_to_path $(git rev-parse annotated))" && | |
240 | ||
241 | keep="$(basename "$(ls $packdir/pack-*.pack)")" && | |
242 | cruft="$(echo $keep | git pack-objects --cruft \ | |
243 | --cruft-expiration=750.seconds.ago \ | |
244 | $packdir/pack)" && | |
245 | test-tool pack-mtimes "pack-$cruft.mtimes" >actual.raw && | |
246 | cut -f1 -d" " <actual.raw | sort >actual && | |
247 | ||
248 | ( | |
249 | cat objects && | |
250 | git rev-parse annotated | |
251 | ) >expect.raw && | |
252 | sort <expect.raw >expect && | |
253 | ||
254 | test_cmp expect actual && | |
255 | cat actual | |
256 | ) | |
257 | ' | |
258 | ||
259 | test_expect_success 'cruft commits rescue parents, trees' ' | |
260 | git init repo && | |
261 | test_when_finished "rm -fr repo" && | |
262 | ( | |
263 | cd repo && | |
264 | ||
265 | test_commit packed && | |
266 | git repack -Ad && | |
267 | ||
268 | test_commit old && | |
269 | test_commit new && | |
270 | ||
271 | git rev-list --objects --no-object-names packed..new >objects && | |
272 | while read object | |
273 | do | |
274 | test-tool chmtime -1000 \ | |
275 | "$objdir/$(test_oid_to_path $object)" | |
276 | done <objects && | |
277 | test-tool chmtime +500 "$objdir/$(test_oid_to_path \ | |
278 | $(git rev-parse HEAD))" && | |
279 | ||
280 | keep="$(basename "$(ls $packdir/pack-*.pack)")" && | |
281 | cruft="$(echo $keep | git pack-objects --cruft \ | |
282 | --cruft-expiration=750.seconds.ago \ | |
283 | $packdir/pack)" && | |
284 | test-tool pack-mtimes "pack-$cruft.mtimes" >actual.raw && | |
285 | ||
286 | cut -d" " -f1 <actual.raw | sort >actual && | |
287 | sort <objects >expect && | |
288 | ||
289 | test_cmp expect actual | |
290 | ) | |
291 | ' | |
292 | ||
293 | test_expect_success 'cruft trees rescue sub-trees, blobs' ' | |
294 | git init repo && | |
295 | test_when_finished "rm -fr repo" && | |
296 | ( | |
297 | cd repo && | |
298 | ||
299 | test_commit packed && | |
300 | git repack -Ad && | |
301 | ||
302 | mkdir -p dir/sub && | |
303 | echo foo >foo && | |
304 | echo bar >dir/bar && | |
305 | echo baz >dir/sub/baz && | |
306 | ||
307 | test_tick && | |
308 | git add . && | |
309 | git commit -m "pruned" && | |
310 | ||
311 | test-tool chmtime -1000 "$objdir/$(test_oid_to_path $(git rev-parse HEAD))" && | |
312 | test-tool chmtime -1000 "$objdir/$(test_oid_to_path $(git rev-parse HEAD^{tree}))" && | |
313 | test-tool chmtime -1000 "$objdir/$(test_oid_to_path $(git rev-parse HEAD:foo))" && | |
314 | test-tool chmtime -500 "$objdir/$(test_oid_to_path $(git rev-parse HEAD:dir))" && | |
315 | test-tool chmtime -1000 "$objdir/$(test_oid_to_path $(git rev-parse HEAD:dir/bar))" && | |
316 | test-tool chmtime -1000 "$objdir/$(test_oid_to_path $(git rev-parse HEAD:dir/sub))" && | |
317 | test-tool chmtime -1000 "$objdir/$(test_oid_to_path $(git rev-parse HEAD:dir/sub/baz))" && | |
318 | ||
319 | keep="$(basename "$(ls $packdir/pack-*.pack)")" && | |
320 | cruft="$(echo $keep | git pack-objects --cruft \ | |
321 | --cruft-expiration=750.seconds.ago \ | |
322 | $packdir/pack)" && | |
323 | test-tool pack-mtimes "pack-$cruft.mtimes" >actual.raw && | |
324 | cut -f1 -d" " <actual.raw | sort >actual && | |
325 | ||
326 | git rev-parse HEAD:dir HEAD:dir/bar HEAD:dir/sub HEAD:dir/sub/baz >expect.raw && | |
327 | sort <expect.raw >expect && | |
328 | ||
329 | test_cmp expect actual | |
330 | ) | |
331 | ' | |
332 | ||
333 | test_expect_success 'expired objects are pruned' ' | |
334 | git init repo && | |
335 | test_when_finished "rm -fr repo" && | |
336 | ( | |
337 | cd repo && | |
338 | ||
339 | test_commit packed && | |
340 | git repack -Ad && | |
341 | ||
342 | test_commit pruned && | |
343 | ||
344 | git rev-list --objects --no-object-names packed..pruned >objects && | |
345 | while read object | |
346 | do | |
347 | test-tool chmtime -1000 \ | |
348 | "$objdir/$(test_oid_to_path $object)" | |
349 | done <objects && | |
350 | ||
351 | keep="$(basename "$(ls $packdir/pack-*.pack)")" && | |
352 | cruft="$(echo $keep | git pack-objects --cruft \ | |
353 | --cruft-expiration=750.seconds.ago \ | |
354 | $packdir/pack)" && | |
355 | ||
356 | test-tool pack-mtimes "pack-$cruft.mtimes" >actual && | |
357 | test_must_be_empty actual | |
358 | ) | |
359 | ' | |
b7573536 | 360 | |
f9825d1c TB |
361 | test_expect_success 'repack --cruft generates a cruft pack' ' |
362 | git init repo && | |
363 | test_when_finished "rm -fr repo" && | |
364 | ( | |
365 | cd repo && | |
366 | ||
367 | test_commit reachable && | |
368 | git branch -M main && | |
369 | git checkout --orphan other && | |
370 | test_commit unreachable && | |
371 | ||
372 | git checkout main && | |
373 | git branch -D other && | |
374 | git tag -d unreachable && | |
375 | # objects are not cruft if they are contained in the reflogs | |
376 | git reflog expire --all --expire=all && | |
377 | ||
378 | git rev-list --objects --all --no-object-names >reachable.raw && | |
379 | git cat-file --batch-all-objects --batch-check="%(objectname)" >objects && | |
380 | sort <reachable.raw >reachable && | |
381 | comm -13 reachable objects >unreachable && | |
382 | ||
383 | git repack --cruft -d && | |
384 | ||
385 | cruft=$(basename $(ls $packdir/pack-*.mtimes) .mtimes) && | |
386 | pack=$(basename $(ls $packdir/pack-*.pack | grep -v $cruft) .pack) && | |
387 | ||
388 | git show-index <$packdir/$pack.idx >actual.raw && | |
389 | cut -f2 -d" " actual.raw | sort >actual && | |
390 | test_cmp reachable actual && | |
391 | ||
392 | git show-index <$packdir/$cruft.idx >actual.raw && | |
393 | cut -f2 -d" " actual.raw | sort >actual && | |
394 | test_cmp unreachable actual | |
395 | ) | |
396 | ' | |
397 | ||
398 | test_expect_success 'loose objects mtimes upsert others' ' | |
399 | git init repo && | |
400 | test_when_finished "rm -fr repo" && | |
401 | ( | |
402 | cd repo && | |
403 | ||
404 | test_commit reachable && | |
405 | git repack -Ad && | |
406 | git branch -M main && | |
407 | ||
408 | git checkout --orphan other && | |
409 | test_commit cruft && | |
410 | # incremental repack, leaving existing objects loose (so | |
411 | # they can be "freshened") | |
412 | git repack && | |
413 | ||
414 | tip="$(git rev-parse cruft)" && | |
415 | path="$objdir/$(test_oid_to_path "$tip")" && | |
416 | test-tool chmtime --get +1000 "$path" >expect && | |
417 | ||
418 | git checkout main && | |
419 | git branch -D other && | |
420 | git tag -d cruft && | |
421 | git reflog expire --all --expire=all && | |
422 | ||
423 | git repack --cruft -d && | |
424 | ||
425 | mtimes="$(basename $(ls $packdir/pack-*.mtimes))" && | |
426 | test-tool pack-mtimes "$mtimes" >actual.raw && | |
427 | grep "$tip" actual.raw | cut -d" " -f2 >actual && | |
428 | test_cmp expect actual | |
429 | ) | |
430 | ' | |
431 | ||
432 | test_expect_success 'cruft packs are not included in geometric repack' ' | |
433 | git init repo && | |
434 | test_when_finished "rm -fr repo" && | |
435 | ( | |
436 | cd repo && | |
437 | ||
438 | test_commit reachable && | |
439 | git repack -Ad && | |
440 | git branch -M main && | |
441 | ||
442 | git checkout --orphan other && | |
443 | test_commit cruft && | |
444 | git repack -d && | |
445 | ||
446 | git checkout main && | |
447 | git branch -D other && | |
448 | git tag -d cruft && | |
449 | git reflog expire --all --expire=all && | |
450 | ||
451 | git repack --cruft && | |
452 | ||
453 | find $packdir -type f | sort >before && | |
454 | git repack --geometric=2 -d && | |
455 | find $packdir -type f | sort >after && | |
456 | ||
457 | test_cmp before after | |
458 | ) | |
459 | ' | |
460 | ||
461 | test_expect_success 'repack --geometric collects once-cruft objects' ' | |
462 | git init repo && | |
463 | test_when_finished "rm -fr repo" && | |
464 | ( | |
465 | cd repo && | |
466 | ||
467 | test_commit reachable && | |
468 | git repack -Ad && | |
469 | git branch -M main && | |
470 | ||
471 | git checkout --orphan other && | |
472 | git rm -rf . && | |
473 | test_commit --no-tag cruft && | |
474 | cruft="$(git rev-parse HEAD)" && | |
475 | ||
476 | git checkout main && | |
477 | git branch -D other && | |
478 | git reflog expire --all --expire=all && | |
479 | ||
480 | # Pack the objects created in the previous step into a cruft | |
481 | # pack. Intentionally leave loose copies of those objects | |
482 | # around so we can pick them up in a subsequent --geometric | |
483 | # reapack. | |
484 | git repack --cruft && | |
485 | ||
486 | # Now make those objects reachable, and ensure that they are | |
487 | # packed into the new pack created via a --geometric repack. | |
488 | git update-ref refs/heads/other $cruft && | |
489 | ||
490 | # Without this object, the set of unpacked objects is exactly | |
491 | # the set of objects already in the cruft pack. Tweak that set | |
492 | # to ensure we do not overwrite the cruft pack entirely. | |
493 | test_commit reachable2 && | |
494 | ||
495 | find $packdir -name "pack-*.idx" | sort >before && | |
496 | git repack --geometric=2 -d && | |
497 | find $packdir -name "pack-*.idx" | sort >after && | |
498 | ||
499 | { | |
500 | git rev-list --objects --no-object-names $cruft && | |
501 | git rev-list --objects --no-object-names reachable..reachable2 | |
502 | } >want.raw && | |
503 | sort want.raw >want && | |
504 | ||
505 | pack=$(comm -13 before after) && | |
506 | git show-index <$pack >objects.raw && | |
507 | ||
508 | cut -d" " -f2 objects.raw | sort >got && | |
509 | ||
510 | test_cmp want got | |
511 | ) | |
512 | ' | |
513 | ||
514 | test_expect_success 'cruft repack with no reachable objects' ' | |
515 | git init repo && | |
516 | test_when_finished "rm -fr repo" && | |
517 | ( | |
518 | cd repo && | |
519 | ||
520 | test_commit base && | |
521 | git repack -ad && | |
522 | ||
523 | base="$(git rev-parse base)" && | |
524 | ||
525 | git for-each-ref --format="delete %(refname)" >in && | |
526 | git update-ref --stdin <in && | |
527 | git reflog expire --all --expire=all && | |
528 | rm -fr .git/index && | |
529 | ||
530 | git repack --cruft -d && | |
531 | ||
532 | git cat-file -t $base | |
533 | ) | |
534 | ' | |
535 | ||
536 | test_expect_success 'cruft repack ignores --max-pack-size' ' | |
537 | git init max-pack-size && | |
538 | ( | |
539 | cd max-pack-size && | |
540 | test_commit base && | |
541 | # two cruft objects which exceed the maximum pack size | |
542 | test-tool genrandom foo 1048576 | git hash-object --stdin -w && | |
543 | test-tool genrandom bar 1048576 | git hash-object --stdin -w && | |
544 | git repack --cruft --max-pack-size=1M && | |
545 | find $packdir -name "*.mtimes" >cruft && | |
546 | test_line_count = 1 cruft && | |
547 | test-tool pack-mtimes "$(basename "$(cat cruft)")" >objects && | |
548 | test_line_count = 2 objects | |
549 | ) | |
550 | ' | |
551 | ||
552 | test_expect_success 'cruft repack ignores pack.packSizeLimit' ' | |
553 | ( | |
554 | cd max-pack-size && | |
555 | # repack everything back together to remove the existing cruft | |
556 | # pack (but to keep its objects) | |
557 | git repack -adk && | |
558 | git -c pack.packSizeLimit=1M repack --cruft && | |
559 | # ensure the same post condition is met when --max-pack-size | |
560 | # would otherwise be inferred from the configuration | |
561 | find $packdir -name "*.mtimes" >cruft && | |
562 | test_line_count = 1 cruft && | |
563 | test-tool pack-mtimes "$(basename "$(cat cruft)")" >objects && | |
564 | test_line_count = 2 objects | |
565 | ) | |
566 | ' | |
567 | ||
4571324b TB |
568 | test_expect_success 'cruft repack respects repack.cruftWindow' ' |
569 | git init repo && | |
570 | test_when_finished "rm -fr repo" && | |
571 | ( | |
572 | cd repo && | |
573 | ||
574 | test_commit base && | |
575 | ||
576 | GIT_TRACE2_EVENT=$(pwd)/event.trace \ | |
577 | git -c pack.window=1 -c repack.cruftWindow=2 repack \ | |
578 | --cruft --window=3 && | |
579 | ||
580 | grep "pack-objects.*--window=2.*--cruft" event.trace | |
581 | ) | |
582 | ' | |
583 | ||
584 | test_expect_success 'cruft repack respects --window by default' ' | |
585 | git init repo && | |
586 | test_when_finished "rm -fr repo" && | |
587 | ( | |
588 | cd repo && | |
589 | ||
590 | test_commit base && | |
591 | ||
592 | GIT_TRACE2_EVENT=$(pwd)/event.trace \ | |
593 | git -c pack.window=2 repack --cruft --window=3 && | |
594 | ||
595 | grep "pack-objects.*--window=3.*--cruft" event.trace | |
596 | ) | |
597 | ' | |
598 | ||
599 | test_expect_success 'cruft repack respects --quiet' ' | |
600 | git init repo && | |
601 | test_when_finished "rm -fr repo" && | |
602 | ( | |
603 | cd repo && | |
604 | ||
605 | test_commit base && | |
606 | GIT_PROGRESS_DELAY=0 git repack --cruft --quiet 2>err && | |
607 | test_must_be_empty err | |
608 | ) | |
609 | ' | |
610 | ||
611 | test_expect_success 'cruft --local drops unreachable objects' ' | |
612 | git init alternate && | |
613 | git init repo && | |
614 | test_when_finished "rm -fr alternate repo" && | |
615 | ||
616 | test_commit -C alternate base && | |
617 | # Pack all objects in alterate so that the cruft repack in "repo" sees | |
618 | # the object it dropped due to `--local` as packed. Otherwise this | |
619 | # object would not appear packed anywhere (since it is not packed in | |
620 | # alternate and likewise not part of the cruft pack in the other repo | |
621 | # because of `--local`). | |
622 | git -C alternate repack -ad && | |
623 | ||
624 | ( | |
625 | cd repo && | |
626 | ||
627 | object="$(git -C ../alternate rev-parse HEAD:base.t)" && | |
628 | git -C ../alternate cat-file -p $object >contents && | |
629 | ||
630 | # Write some reachable objects and two unreachable ones: one | |
631 | # that the alternate has and another that is unique. | |
632 | test_commit other && | |
633 | git hash-object -w -t blob contents && | |
634 | cruft="$(echo cruft | git hash-object -w -t blob --stdin)" && | |
635 | ||
636 | ( cd ../alternate/.git/objects && pwd ) \ | |
637 | >.git/objects/info/alternates && | |
638 | ||
639 | test_path_is_file $objdir/$(test_oid_to_path $cruft) && | |
640 | test_path_is_file $objdir/$(test_oid_to_path $object) && | |
641 | ||
642 | git repack -d --cruft --local && | |
643 | ||
644 | test-tool pack-mtimes "$(basename $(ls $packdir/pack-*.mtimes))" \ | |
645 | >objects && | |
646 | ! grep $object objects && | |
647 | grep $cruft objects | |
648 | ) | |
649 | ' | |
650 | ||
ddee3703 TB |
651 | test_expect_success 'MIDX bitmaps tolerate reachable cruft objects' ' |
652 | git init repo && | |
653 | test_when_finished "rm -fr repo" && | |
654 | ( | |
655 | cd repo && | |
656 | ||
657 | test_commit reachable && | |
658 | test_commit cruft && | |
659 | unreachable="$(git rev-parse cruft)" && | |
660 | ||
661 | git reset --hard $unreachable^ && | |
662 | git tag -d cruft && | |
663 | git reflog expire --all --expire=all && | |
664 | ||
665 | git repack --cruft -d && | |
666 | ||
667 | # resurrect the unreachable object via a new commit. the | |
668 | # new commit will get selected for a bitmap, but be | |
669 | # missing one of its parents from the selected packs. | |
670 | git reset --hard $unreachable && | |
671 | test_commit resurrect && | |
672 | ||
673 | git repack --write-midx --write-bitmap-index --geometric=2 -d | |
674 | ) | |
675 | ' | |
676 | ||
b7573536 | 677 | test_done |