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