Raw
1 #!/bin/sh
2 #
3 # Copyright (c) 2005 Junio C Hamano
4 #
5
6 test_description='git pack-object'
7
8 . ./test-lib.sh
9
10 test_expect_success 'setup' '
11 rm -f .git/index* &&
12 test-tool genzeros 4096 | tr "\000" "a" >a &&
13 test-tool genzeros 4096 | tr "\000" "b" >b &&
14 test-tool genzeros 4096 | tr "\000" "c" >c &&
15 test-tool genrandom "seed a" 2097152 >a_big &&
16 test-tool genrandom "seed b" 2097152 >b_big &&
17 git update-index --add a a_big b b_big c &&
18 cat c >d && echo foo >>d && git update-index --add d &&
19 tree=$(git write-tree) &&
20 commit=$(git commit-tree $tree </dev/null) &&
21 {
22 echo $tree &&
23 echo $commit &&
24 git ls-tree $tree | sed -e "s/.* \\([0-9a-f]*\\) .*/\\1/"
25 } >obj-list &&
26 {
27 git diff-tree --root -p $commit &&
28 while read object
29 do
30 t=$(git cat-file -t $object) &&
31 git cat-file $t $object || return 1
32 done <obj-list
33 } >expect
34 '
35
36 test_expect_success 'setup pack-object <stdin' '
37 git init pack-object-stdin &&
38 test_commit -C pack-object-stdin one &&
39 test_commit -C pack-object-stdin two
40
41 '
42
43 test_expect_success 'pack-object <stdin parsing: basic [|--revs]' '
44 cat >in <<-EOF &&
45 $(git -C pack-object-stdin rev-parse one)
46 EOF
47
48 git -C pack-object-stdin pack-objects basic-stdin <in &&
49 idx=$(echo pack-object-stdin/basic-stdin-*.idx) &&
50 git show-index <"$idx" >actual &&
51 test_line_count = 1 actual &&
52
53 git -C pack-object-stdin pack-objects --revs basic-stdin-revs <in &&
54 idx=$(echo pack-object-stdin/basic-stdin-revs-*.idx) &&
55 git show-index <"$idx" >actual &&
56 test_line_count = 3 actual
57 '
58
59 test_expect_success 'pack-object <stdin parsing: [|--revs] bad line' '
60 cat >in <<-EOF &&
61 $(git -C pack-object-stdin rev-parse one)
62 garbage
63 $(git -C pack-object-stdin rev-parse two)
64 EOF
65
66 sed "s/^> //g" >err.expect <<-EOF &&
67 fatal: expected object ID, got garbage:
68 > garbage
69
70 EOF
71 test_must_fail git -C pack-object-stdin pack-objects bad-line-stdin <in 2>err.actual &&
72 test_cmp err.expect err.actual &&
73
74 cat >err.expect <<-EOF &&
75 fatal: bad revision '"'"'garbage'"'"'
76 EOF
77 test_must_fail git -C pack-object-stdin pack-objects --revs bad-line-stdin-revs <in 2>err.actual &&
78 test_cmp err.expect err.actual
79 '
80
81 test_expect_success 'pack-object <stdin parsing: [|--revs] empty line' '
82 cat >in <<-EOF &&
83 $(git -C pack-object-stdin rev-parse one)
84
85 $(git -C pack-object-stdin rev-parse two)
86 EOF
87
88 sed -e "s/^> //g" -e "s/Z$//g" >err.expect <<-EOF &&
89 fatal: expected object ID, got garbage:
90 > Z
91
92 EOF
93 test_must_fail git -C pack-object-stdin pack-objects empty-line-stdin <in 2>err.actual &&
94 test_cmp err.expect err.actual &&
95
96 git -C pack-object-stdin pack-objects --revs empty-line-stdin-revs <in &&
97 idx=$(echo pack-object-stdin/empty-line-stdin-revs-*.idx) &&
98 git show-index <"$idx" >actual &&
99 test_line_count = 3 actual
100 '
101
102 test_expect_success 'pack-object <stdin parsing: [|--revs] with --stdin' '
103 cat >in <<-EOF &&
104 $(git -C pack-object-stdin rev-parse one)
105 $(git -C pack-object-stdin rev-parse two)
106 EOF
107
108 # There is the "--stdin-packs is incompatible with --revs"
109 # test below, but we should make sure that the revision.c
110 # --stdin is not picked up
111 cat >err.expect <<-EOF &&
112 fatal: disallowed abbreviated or ambiguous option '"'"'stdin'"'"'
113 EOF
114 test_must_fail git -C pack-object-stdin pack-objects stdin-with-stdin-option --stdin <in 2>err.actual &&
115 test_cmp err.expect err.actual &&
116
117 test_must_fail git -C pack-object-stdin pack-objects --stdin --revs stdin-with-stdin-option-revs 2>err.actual <in &&
118 test_cmp err.expect err.actual
119 '
120
121 test_expect_success 'pack-object <stdin parsing: --stdin-packs handles garbage' '
122 cat >in <<-EOF &&
123 $(git -C pack-object-stdin rev-parse one)
124 $(git -C pack-object-stdin rev-parse two)
125 EOF
126
127 # That we get "two" and not "one" has to do with OID
128 # ordering. It happens to be the same here under SHA-1 and
129 # SHA-256. See commentary in pack-objects.c
130 cat >err.expect <<-EOF &&
131 fatal: could not find pack '"'"'$(git -C pack-object-stdin rev-parse two)'"'"'
132 EOF
133 test_must_fail git \
134 -C pack-object-stdin \
135 pack-objects stdin-with-stdin-option --stdin-packs \
136 <in 2>err.actual &&
137 test_cmp err.expect err.actual
138 '
139
140 # usage: check_deltas <stderr_from_pack_objects> <cmp_op> <nr_deltas>
141 # e.g.: check_deltas stderr -gt 0
142 check_deltas() {
143 deltas=$(sed -n 's/Total [0-9][0-9]* (delta \([0-9][0-9]*\)).*/\1/p' "$1") &&
144 shift &&
145 if ! test "$deltas" "$@"
146 then
147 echo >&2 "unexpected number of deltas (compared $delta $*)"
148 return 1
149 fi
150 }
151
152 test_expect_success 'pack without delta' '
153 packname_1=$(git pack-objects --progress --window=0 test-1 \
154 <obj-list 2>stderr) &&
155 check_deltas stderr = 0
156 '
157
158 test_expect_success 'negative window clamps to 0' '
159 git pack-objects --progress --window=-1 neg-window <obj-list 2>stderr &&
160 check_deltas stderr = 0
161 '
162
163 test_expect_success 'pack-objects with bogus arguments' '
164 test_must_fail git pack-objects --window=0 test-1 blah blah <obj-list
165 '
166
167 check_unpack () {
168 local packname="$1" &&
169 local object_list="$2" &&
170 local git_config="$3" &&
171 test_when_finished "rm -rf git2" &&
172 git $git_config init --bare git2 &&
173 (
174 git $git_config -C git2 unpack-objects -n <"$packname".pack &&
175 git $git_config -C git2 unpack-objects <"$packname".pack &&
176 git $git_config -C git2 cat-file --batch-check="%(objectname)"
177 ) <"$object_list" >current &&
178 cmp "$object_list" current
179 }
180
181 test_expect_success 'unpack without delta' '
182 check_unpack test-1-${packname_1} obj-list
183 '
184
185 BATCH_CONFIGURATION='-c core.fsync=loose-object -c core.fsyncmethod=batch'
186
187 test_expect_success 'unpack without delta (core.fsyncmethod=batch)' '
188 check_unpack test-1-${packname_1} obj-list "$BATCH_CONFIGURATION"
189 '
190
191 test_expect_success 'pack with REF_DELTA' '
192 packname_2=$(git pack-objects --progress test-2 <obj-list 2>stderr) &&
193 check_deltas stderr -gt 0 &&
194 test-tool pack-deltas --list-deltas test-2-$packname_2.idx >deltas &&
195 test_grep " REF_DELTA " deltas
196 '
197
198 test_expect_success 'unpack with REF_DELTA' '
199 check_unpack test-2-${packname_2} obj-list
200 '
201
202 test_expect_success 'unpack with REF_DELTA (core.fsyncmethod=batch)' '
203 check_unpack test-2-${packname_2} obj-list "$BATCH_CONFIGURATION"
204 '
205
206 test_expect_success 'pack with OFS_DELTA' '
207 packname_3=$(git pack-objects --progress --delta-base-offset test-3 \
208 <obj-list 2>stderr) &&
209 check_deltas stderr -gt 0 &&
210 test-tool pack-deltas --list-deltas test-3-$packname_3.idx >deltas &&
211 test_grep " OFS_DELTA " deltas
212 '
213
214 test_expect_success 'pack without REF_DELTA' '
215 git pack-objects --no-ref-delta --stdout <obj-list >no-ref.pack &&
216 git index-pack -o no-ref.idx no-ref.pack &&
217
218 test-tool pack-deltas --list-deltas no-ref.idx >deltas &&
219 test_must_be_empty deltas
220 '
221
222 test_expect_success 'pack without REF_DELTA with OFS_DELTA' '
223 git pack-objects --delta-base-offset --no-ref-delta --stdout \
224 <obj-list >no-ref-ofs.pack &&
225 git index-pack -o no-ref-ofs.idx no-ref-ofs.pack &&
226
227 test-tool pack-deltas --list-deltas no-ref-ofs.idx >deltas &&
228 test_grep " OFS_DELTA " deltas &&
229 test_grep ! " REF_DELTA " deltas
230 '
231
232 test_expect_success 'pack without REF_DELTA reuses deltas as OFS_DELTA' '
233 # Install the REF_DELTA pack above and disable delta search, so any
234 # output delta must be a reused REF_DELTA rewritten as OFS_DELTA.
235 test_when_finished "rm -f .git/objects/pack/pack-$packname_2.*" &&
236 git index-pack --stdin <test-2-${packname_2}.pack >/dev/null &&
237
238 git pack-objects --window=0 --delta-base-offset \
239 --no-ref-delta --stdout <obj-list >reused.pack &&
240 git index-pack -o reused.idx reused.pack &&
241 test-tool pack-deltas --list-deltas reused.idx >deltas &&
242 test_grep " OFS_DELTA " deltas &&
243 test_grep ! " REF_DELTA " deltas
244 '
245
246 test_expect_success 'pack without REF_DELTA skips excluded delta bases' '
247 test_when_finished "git read-tree $tree" &&
248
249 echo bar >>d &&
250 git update-index --add d &&
251 thin_tree=$(git write-tree) &&
252 thin_commit=$(git commit-tree $thin_tree -p $commit </dev/null) &&
253
254 {
255 echo $thin_commit &&
256 echo ^$commit
257 } >thin-revs &&
258
259 # Each type appears only once in the output, so any delta must
260 # use an excluded base and therefore be a REF_DELTA.
261 git pack-objects --thin --stdout --revs \
262 <thin-revs >thin.pack &&
263 git index-pack --fix-thin --stdin thin-fixed.pack \
264 <thin.pack >/dev/null &&
265
266 test-tool pack-deltas --list-deltas thin-fixed.idx >deltas &&
267 test_grep ! " OFS_DELTA " deltas &&
268 test_grep " REF_DELTA " deltas &&
269
270 # Store the REF_DELTA entries above and disable delta search below,
271 # so any output delta would have to reuse an excluded-base
272 # REF_DELTA.
273 git index-pack --stdin <thin-fixed.pack >/dev/null &&
274
275 git pack-objects --thin --window=0 --stdout --revs \
276 --delta-base-offset --no-ref-delta \
277 <thin-revs >no-ref-thin.pack &&
278 git index-pack --fix-thin --stdin no-ref-thin-fixed.pack \
279 <no-ref-thin.pack >/dev/null &&
280
281 test-tool pack-deltas --list-deltas no-ref-thin-fixed.idx >deltas &&
282 test_must_be_empty deltas
283 '
284
285 test_expect_success 'unpack with OFS_DELTA' '
286 check_unpack test-3-${packname_3} obj-list
287 '
288
289 test_expect_success 'unpack with OFS_DELTA (core.fsyncmethod=batch)' '
290 check_unpack test-3-${packname_3} obj-list "$BATCH_CONFIGURATION"
291 '
292
293 test_expect_success PERL_TEST_HELPERS 'compare delta flavors' '
294 perl -e '\''
295 defined($_ = -s $_) or die for @ARGV;
296 exit 1 if $ARGV[0] <= $ARGV[1];
297 '\'' test-2-$packname_2.pack test-3-$packname_3.pack
298 '
299
300 check_use_objects () {
301 test_when_finished "rm -rf git2" &&
302 git init --bare git2 &&
303 cp "$1".pack "$1".idx git2/objects/pack &&
304 (
305 cd git2 &&
306 git diff-tree --root -p $commit &&
307 while read object
308 do
309 t=$(git cat-file -t $object) &&
310 git cat-file $t $object || exit 1
311 done
312 ) <obj-list >current &&
313 cmp expect current
314 }
315
316 test_expect_success 'use packed objects' '
317 check_use_objects test-1-${packname_1}
318 '
319
320 test_expect_success 'use packed deltified (REF_DELTA) objects' '
321 check_use_objects test-2-${packname_2}
322 '
323
324 test_expect_success 'use packed deltified (OFS_DELTA) objects' '
325 check_use_objects test-3-${packname_3}
326 '
327
328 test_expect_success 'survive missing objects/pack directory' '
329 (
330 rm -fr missing-pack &&
331 mkdir missing-pack &&
332 cd missing-pack &&
333 git init &&
334 GOP=.git/objects/pack &&
335 rm -fr $GOP &&
336 git index-pack --stdin --keep=test <../test-3-${packname_3}.pack &&
337 test -f $GOP/pack-${packname_3}.pack &&
338 cmp $GOP/pack-${packname_3}.pack ../test-3-${packname_3}.pack &&
339 test -f $GOP/pack-${packname_3}.idx &&
340 cmp $GOP/pack-${packname_3}.idx ../test-3-${packname_3}.idx &&
341 test -f $GOP/pack-${packname_3}.keep
342 )
343 '
344
345 test_expect_success 'verify pack' '
346 git verify-pack test-1-${packname_1}.idx \
347 test-2-${packname_2}.idx \
348 test-3-${packname_3}.idx
349 '
350
351 test_expect_success 'verify pack -v' '
352 git verify-pack -v test-1-${packname_1}.idx \
353 test-2-${packname_2}.idx \
354 test-3-${packname_3}.idx
355 '
356
357 test_expect_success 'verify-pack catches mismatched .idx and .pack files' '
358 cat test-1-${packname_1}.idx >test-3.idx &&
359 cat test-2-${packname_2}.pack >test-3.pack &&
360 if git verify-pack test-3.idx
361 then false
362 else :;
363 fi
364 '
365
366 test_expect_success 'verify-pack catches a corrupted pack signature' '
367 cat test-1-${packname_1}.pack >test-3.pack &&
368 echo | dd of=test-3.pack count=1 bs=1 conv=notrunc seek=2 &&
369 if git verify-pack test-3.idx
370 then false
371 else :;
372 fi
373 '
374
375 test_expect_success 'verify-pack catches a corrupted pack version' '
376 cat test-1-${packname_1}.pack >test-3.pack &&
377 echo | dd of=test-3.pack count=1 bs=1 conv=notrunc seek=7 &&
378 if git verify-pack test-3.idx
379 then false
380 else :;
381 fi
382 '
383
384 test_expect_success 'verify-pack catches a corrupted type/size of the 1st packed object data' '
385 cat test-1-${packname_1}.pack >test-3.pack &&
386 echo | dd of=test-3.pack count=1 bs=1 conv=notrunc seek=12 &&
387 if git verify-pack test-3.idx
388 then false
389 else :;
390 fi
391 '
392
393 test_expect_success 'verify-pack catches a corrupted sum of the index file itself' '
394 l=$(wc -c <test-3.idx) &&
395 l=$(expr $l - 20) &&
396 cat test-1-${packname_1}.pack >test-3.pack &&
397 printf "%20s" "" | dd of=test-3.idx count=20 bs=1 conv=notrunc seek=$l &&
398 if git verify-pack test-3.pack
399 then false
400 else :;
401 fi
402 '
403
404 test_expect_success 'build pack index for an existing pack' '
405 cat test-1-${packname_1}.pack >test-3.pack &&
406 git index-pack -o tmp.idx test-3.pack &&
407 cmp tmp.idx test-1-${packname_1}.idx &&
408
409 git index-pack test-3.pack &&
410 cmp test-3.idx test-1-${packname_1}.idx &&
411
412 cat test-2-${packname_2}.pack >test-3.pack &&
413 git index-pack -o tmp.idx test-2-${packname_2}.pack &&
414 cmp tmp.idx test-2-${packname_2}.idx &&
415
416 git index-pack test-3.pack &&
417 cmp test-3.idx test-2-${packname_2}.idx &&
418
419 cat test-3-${packname_3}.pack >test-3.pack &&
420 git index-pack -o tmp.idx test-3-${packname_3}.pack &&
421 cmp tmp.idx test-3-${packname_3}.idx &&
422
423 git index-pack test-3.pack &&
424 cmp test-3.idx test-3-${packname_3}.idx &&
425
426 cat test-1-${packname_1}.pack >test-4.pack &&
427 rm -f test-4.keep &&
428 git index-pack --keep=why test-4.pack &&
429 cmp test-1-${packname_1}.idx test-4.idx &&
430 test -f test-4.keep &&
431
432 :
433 '
434
435 test_expect_success 'unpacking with --strict' '
436
437 for j in a b c d e f g
438 do
439 for i in 0 1 2 3 4 5 6 7 8 9
440 do
441 o=$(echo $j$i | git hash-object -w --stdin) &&
442 echo "100644 $o 0 $j$i" || return 1
443 done
444 done >LIST &&
445 rm -f .git/index &&
446 git update-index --index-info <LIST &&
447 LIST=$(git write-tree) &&
448 rm -f .git/index &&
449 head -n 10 LIST | git update-index --index-info &&
450 LI=$(git write-tree) &&
451 rm -f .git/index &&
452 tail -n 10 LIST | git update-index --index-info &&
453 ST=$(git write-tree) &&
454 git rev-list --objects "$LIST" "$LI" "$ST" >actual &&
455 PACK5=$( git pack-objects test-5 <actual ) &&
456 PACK6=$( test_write_lines "$LIST" "$LI" "$ST" | git pack-objects test-6 ) &&
457 test_create_repo test-5 &&
458 (
459 cd test-5 &&
460 git unpack-objects --strict <../test-5-$PACK5.pack &&
461 git ls-tree -r $LIST &&
462 git ls-tree -r $LI &&
463 git ls-tree -r $ST
464 ) &&
465 test_create_repo test-6 &&
466 (
467 # tree-only into empty repo -- many unreachables
468 cd test-6 &&
469 test_must_fail git unpack-objects --strict <../test-6-$PACK6.pack
470 ) &&
471 (
472 # already populated -- no unreachables
473 cd test-5 &&
474 git unpack-objects --strict <../test-6-$PACK6.pack
475 )
476 '
477
478 test_expect_success 'index-pack with --strict' '
479
480 for j in a b c d e f g
481 do
482 for i in 0 1 2 3 4 5 6 7 8 9
483 do
484 o=$(echo $j$i | git hash-object -w --stdin) &&
485 echo "100644 $o 0 $j$i" || return 1
486 done
487 done >LIST &&
488 rm -f .git/index &&
489 git update-index --index-info <LIST &&
490 LIST=$(git write-tree) &&
491 rm -f .git/index &&
492 head -n 10 LIST | git update-index --index-info &&
493 LI=$(git write-tree) &&
494 rm -f .git/index &&
495 tail -n 10 LIST | git update-index --index-info &&
496 ST=$(git write-tree) &&
497 git rev-list --objects "$LIST" "$LI" "$ST" >actual &&
498 PACK5=$( git pack-objects test-5 <actual ) &&
499 PACK6=$( test_write_lines "$LIST" "$LI" "$ST" | git pack-objects test-6 ) &&
500 test_create_repo test-7 &&
501 (
502 cd test-7 &&
503 git index-pack --strict --stdin <../test-5-$PACK5.pack &&
504 git ls-tree -r $LIST &&
505 git ls-tree -r $LI &&
506 git ls-tree -r $ST
507 ) &&
508 test_create_repo test-8 &&
509 (
510 # tree-only into empty repo -- many unreachables
511 cd test-8 &&
512 test_must_fail git index-pack --strict --stdin <../test-6-$PACK6.pack
513 ) &&
514 (
515 # already populated -- no unreachables
516 cd test-7 &&
517 git index-pack --strict --stdin <../test-6-$PACK6.pack
518 )
519 '
520
521 test_expect_success 'setup for --strict and --fsck-objects downgrading fsck msgs' '
522 git init strict &&
523 (
524 cd strict &&
525 test_commit first hello &&
526 cat >commit <<-EOF &&
527 tree $(git rev-parse HEAD^{tree})
528 parent $(git rev-parse HEAD)
529 author A U Thor
530 committer A U Thor
531
532 commit: this is a commit with bad emails
533
534 EOF
535 git hash-object --literally -t commit -w --stdin <commit >commit_list &&
536 git pack-objects test <commit_list >pack-name
537 )
538 '
539
540 test_with_bad_commit () {
541 must_fail_arg="$1" &&
542 must_pass_arg="$2" &&
543 (
544 cd strict &&
545 test_must_fail git index-pack "$must_fail_arg" "test-$(cat pack-name).pack" &&
546 git index-pack "$must_pass_arg" "test-$(cat pack-name).pack"
547 )
548 }
549
550 test_expect_success 'index-pack with --strict downgrading fsck msgs' '
551 test_with_bad_commit --strict --strict="missingEmail=ignore"
552 '
553
554 test_expect_success 'index-pack with --fsck-objects downgrading fsck msgs' '
555 test_with_bad_commit --fsck-objects --fsck-objects="missingEmail=ignore"
556 '
557
558 test_expect_success 'cleanup for --strict and --fsck-objects downgrading fsck msgs' '
559 rm -rf strict
560 '
561
562 test_expect_success 'honor pack.packSizeLimit' '
563 git config pack.packSizeLimit 3m &&
564 packname_10=$(git pack-objects test-10 <obj-list) &&
565 test 2 = $(ls test-10-*.pack | wc -l)
566 '
567
568 test_expect_success 'verify resulting packs' '
569 git verify-pack test-10-*.pack
570 '
571
572 test_expect_success 'tolerate packsizelimit smaller than biggest object' '
573 git config pack.packSizeLimit 1 &&
574 packname_11=$(git pack-objects test-11 <obj-list) &&
575 test 5 = $(ls test-11-*.pack | wc -l)
576 '
577
578 test_expect_success 'verify resulting packs' '
579 git verify-pack test-11-*.pack
580 '
581
582 test_expect_success 'set up pack for non-repo tests' '
583 # make sure we have a pack with no matching index file
584 cp test-1-*.pack foo.pack
585 '
586
587 test_expect_success 'index-pack --stdin complains of non-repo' '
588 nongit test_must_fail git index-pack --object-format=$(test_oid algo) --stdin <foo.pack &&
589 test_path_is_missing non-repo/.git
590 '
591
592 test_expect_success 'index-pack <pack> works in non-repo' '
593 nongit git index-pack --object-format=$(test_oid algo) ../foo.pack &&
594 test_path_is_file foo.idx
595 '
596
597 test_expect_success 'index-pack --strict <pack> works in non-repo' '
598 rm -f foo.idx &&
599 nongit git index-pack --strict --object-format=$(test_oid algo) ../foo.pack &&
600 test_path_is_file foo.idx
601 '
602
603 test_expect_success DEFAULT_HASH_ALGORITHM 'show-index works OK outside a repository' '
604 nongit git show-index <foo.idx
605 '
606
607 for hash in sha1 sha256
608 do
609 test_expect_success 'show-index works OK outside a repository with hash algo passed in via --object-format' '
610 test_when_finished "rm -rf explicit-hash-$hash" &&
611 git init --object-format=$hash explicit-hash-$hash &&
612 test_commit -C explicit-hash-$hash one &&
613 git -C explicit-hash-$hash rev-parse one >in &&
614 git -C explicit-hash-$hash pack-objects explicit-hash-$hash <in &&
615 idx=$(echo explicit-hash-$hash/explicit-hash-$hash*.idx) &&
616 nongit git show-index --object-format=$hash <"$idx" >actual &&
617 test_line_count = 1 actual
618 '
619 done
620
621 test_expect_success !PTHREADS,!FAIL_PREREQS \
622 'index-pack --threads=N or pack.threads=N warns when no pthreads' '
623 test_must_fail git index-pack --threads=2 2>err &&
624 grep ^warning: err >warnings &&
625 test_line_count = 1 warnings &&
626 test_grep -F "no threads support, ignoring --threads=2" err &&
627
628 test_must_fail git -c pack.threads=2 index-pack 2>err &&
629 grep ^warning: err >warnings &&
630 test_line_count = 1 warnings &&
631 test_grep -F "no threads support, ignoring pack.threads" err &&
632
633 test_must_fail git -c pack.threads=2 index-pack --threads=4 2>err &&
634 grep ^warning: err >warnings &&
635 test_line_count = 2 warnings &&
636 test_grep -F "no threads support, ignoring --threads=4" err &&
637 test_grep -F "no threads support, ignoring pack.threads" err
638 '
639
640 test_expect_success !PTHREADS,!FAIL_PREREQS \
641 'pack-objects --threads=N or pack.threads=N warns when no pthreads' '
642 git pack-objects --threads=2 --stdout --all </dev/null >/dev/null 2>err &&
643 grep ^warning: err >warnings &&
644 test_line_count = 1 warnings &&
645 test_grep -F "no threads support, ignoring --threads" err &&
646
647 git -c pack.threads=2 pack-objects --stdout --all </dev/null >/dev/null 2>err &&
648 grep ^warning: err >warnings &&
649 test_line_count = 1 warnings &&
650 test_grep -F "no threads support, ignoring pack.threads" err &&
651
652 git -c pack.threads=2 pack-objects --threads=4 --stdout --all </dev/null >/dev/null 2>err &&
653 grep ^warning: err >warnings &&
654 test_line_count = 2 warnings &&
655 test_grep -F "no threads support, ignoring --threads" err &&
656 test_grep -F "no threads support, ignoring pack.threads" err
657 '
658
659 test_expect_success 'pack-objects in too-many-packs mode' '
660 GIT_TEST_FULL_IN_PACK_ARRAY=1 git repack -ad &&
661 git fsck
662 '
663
664 test_expect_success 'setup: fake a SHA1 hash collision' '
665 git init corrupt &&
666 (
667 cd corrupt &&
668 long_a=$(git hash-object -w ../a | sed -e "s!^..!&/!") &&
669 long_b=$(git hash-object -w ../b | sed -e "s!^..!&/!") &&
670 test -f .git/objects/$long_b &&
671 cp -f .git/objects/$long_a \
672 .git/objects/$long_b
673 )
674 '
675
676 test_expect_success 'make sure index-pack detects the SHA1 collision' '
677 (
678 cd corrupt &&
679 test_must_fail git index-pack -o ../bad.idx ../test-3.pack 2>msg &&
680 test_grep "SHA1 COLLISION FOUND" msg
681 )
682 '
683
684 test_expect_success 'make sure index-pack detects the SHA1 collision (large blobs)' '
685 (
686 cd corrupt &&
687 test_must_fail git -c core.bigfilethreshold=1 index-pack -o ../bad.idx ../test-3.pack 2>msg &&
688 test_grep "SHA1 COLLISION FOUND" msg
689 )
690 '
691
692 test_expect_success 'prefetch objects' '
693 rm -rf server client &&
694
695 git init server &&
696 test_config -C server uploadpack.allowanysha1inwant 1 &&
697 test_config -C server uploadpack.allowfilter 1 &&
698 test_config -C server protocol.version 2 &&
699
700 echo one >server/one &&
701 git -C server add one &&
702 git -C server commit -m one &&
703 git -C server branch one_branch &&
704
705 echo two_a >server/two_a &&
706 echo two_b >server/two_b &&
707 git -C server add two_a two_b &&
708 git -C server commit -m two &&
709
710 echo three >server/three &&
711 git -C server add three &&
712 git -C server commit -m three &&
713 git -C server branch three_branch &&
714
715 # Clone, fetch "two" with blobs excluded, and re-push it. This requires
716 # the client to have the blobs of "two" - verify that these are
717 # prefetched in one batch.
718 git clone --filter=blob:none --single-branch -b one_branch \
719 "file://$(pwd)/server" client &&
720 test_config -C client protocol.version 2 &&
721 TWO=$(git -C server rev-parse three_branch^) &&
722 git -C client fetch --filter=blob:none origin "$TWO" &&
723 GIT_TRACE_PACKET=$(pwd)/trace git -C client push origin "$TWO":refs/heads/two_branch &&
724 grep "fetch> done" trace >donelines &&
725 test_line_count = 1 donelines
726 '
727
728 for hash in sha1 sha256
729 do
730 test_expect_success "verify-pack with $hash packfile" '
731 test_when_finished "rm -rf repo" &&
732 git init --object-format=$hash repo &&
733 test_commit -C repo initial &&
734 git -C repo repack -ad &&
735 git -C repo verify-pack "$(pwd)"/repo/.git/objects/pack/*.idx &&
736 if test $hash = $GIT_TEST_BUILTIN_HASH
737 then
738 nongit git verify-pack "$(pwd)"/repo/.git/objects/pack/*.idx
739 else
740 # We have no way to identify the hash used by packfiles
741 # or indices, so we always fall back to SHA1.
742 nongit test_must_fail git verify-pack "$(pwd)"/repo/.git/objects/pack/*.idx &&
743 # But with an explicit object format we should succeed.
744 nongit git verify-pack --object-format=$hash "$(pwd)"/repo/.git/objects/pack/*.idx
745 fi
746 '
747
748 test_expect_success "index-pack outside of a $hash repository" '
749 test_when_finished "rm -rf repo" &&
750 git init --object-format=$hash repo &&
751 test_commit -C repo initial &&
752 git -C repo repack -ad &&
753 git -C repo index-pack --verify "$(pwd)"/repo/.git/objects/pack/*.pack &&
754 if test $hash = $GIT_TEST_BUILTIN_HASH
755 then
756 nongit git index-pack --verify "$(pwd)"/repo/.git/objects/pack/*.pack
757 else
758 # We have no way to identify the hash used by packfiles
759 # or indices, so we always fall back to SHA1.
760 nongit test_must_fail git index-pack --verify "$(pwd)"/repo/.git/objects/pack/*.pack 2>err &&
761 # But with an explicit object format we should succeed.
762 nongit git index-pack --object-format=$hash --verify "$(pwd)"/repo/.git/objects/pack/*.pack
763 fi
764 '
765 done
766
767 test_expect_success 'valid and invalid --name-hash-versions' '
768 sane_unset GIT_TEST_NAME_HASH_VERSION &&
769
770 # Valid values are hard to verify other than "do not fail".
771 # Performance tests will be more valuable to validate these versions.
772 # Negative values are converted to version 1.
773 for value in -1 1 2
774 do
775 git pack-objects base --all --name-hash-version=$value || return 1
776 done &&
777
778 # Invalid values have clear post-conditions.
779 for value in 0 3
780 do
781 test_must_fail git pack-objects base --all --name-hash-version=$value 2>err &&
782 test_grep "invalid --name-hash-version option" err || return 1
783 done
784 '
785
786 # The following test is not necessarily a permanent choice, but since we do not
787 # have a "name hash version" bit in the .bitmap file format, we cannot write the
788 # hash values into the .bitmap file without risking breakage later.
789 #
790 # TODO: Make these compatible in the future and replace this test with the
791 # expected behavior when both are specified.
792 test_expect_success '--name-hash-version=2 and --write-bitmap-index are incompatible' '
793 git pack-objects base --all --name-hash-version=2 --write-bitmap-index 2>err &&
794 test_grep "currently, --write-bitmap-index requires --name-hash-version=1" err &&
795
796 # --stdout option silently removes --write-bitmap-index
797 git pack-objects --stdout --all --name-hash-version=2 --write-bitmap-index >out 2>err &&
798 test_grep ! "currently, --write-bitmap-index requires --name-hash-version=1" err
799 '
800
801 test_expect_success '--path-walk pack everything' '
802 git -C server rev-parse HEAD >in &&
803 GIT_PROGRESS_DELAY=0 git -C server pack-objects \
804 --stdout --revs --path-walk --progress <in >out.pack 2>err &&
805 test_grep "Compressing objects by path" err &&
806 git -C server index-pack --stdin <out.pack
807 '
808
809 test_expect_success '--path-walk thin pack' '
810 cat >in <<-EOF &&
811 $(git -C server rev-parse HEAD)
812 ^$(git -C server rev-parse HEAD~2)
813 EOF
814 GIT_PROGRESS_DELAY=0 git -C server pack-objects \
815 --thin --stdout --revs --path-walk --progress <in >out.pack 2>err &&
816 test_grep "Compressing objects by path" err &&
817 git -C server index-pack --fix-thin --stdin <out.pack
818 '
819
820 test_done