| 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 | ' |
| 195 | |
| 196 | test_expect_success 'unpack with REF_DELTA' ' |
| 197 | check_unpack test-2-${packname_2} obj-list |
| 198 | ' |
| 199 | |
| 200 | test_expect_success 'unpack with REF_DELTA (core.fsyncmethod=batch)' ' |
| 201 | check_unpack test-2-${packname_2} obj-list "$BATCH_CONFIGURATION" |
| 202 | ' |
| 203 | |
| 204 | test_expect_success 'pack with OFS_DELTA' ' |
| 205 | packname_3=$(git pack-objects --progress --delta-base-offset test-3 \ |
| 206 | <obj-list 2>stderr) && |
| 207 | check_deltas stderr -gt 0 |
| 208 | ' |
| 209 | |
| 210 | test_expect_success 'unpack with OFS_DELTA' ' |
| 211 | check_unpack test-3-${packname_3} obj-list |
| 212 | ' |
| 213 | |
| 214 | test_expect_success 'unpack with OFS_DELTA (core.fsyncmethod=batch)' ' |
| 215 | check_unpack test-3-${packname_3} obj-list "$BATCH_CONFIGURATION" |
| 216 | ' |
| 217 | |
| 218 | test_expect_success PERL_TEST_HELPERS 'compare delta flavors' ' |
| 219 | perl -e '\'' |
| 220 | defined($_ = -s $_) or die for @ARGV; |
| 221 | exit 1 if $ARGV[0] <= $ARGV[1]; |
| 222 | '\'' test-2-$packname_2.pack test-3-$packname_3.pack |
| 223 | ' |
| 224 | |
| 225 | check_use_objects () { |
| 226 | test_when_finished "rm -rf git2" && |
| 227 | git init --bare git2 && |
| 228 | cp "$1".pack "$1".idx git2/objects/pack && |
| 229 | ( |
| 230 | cd git2 && |
| 231 | git diff-tree --root -p $commit && |
| 232 | while read object |
| 233 | do |
| 234 | t=$(git cat-file -t $object) && |
| 235 | git cat-file $t $object || exit 1 |
| 236 | done |
| 237 | ) <obj-list >current && |
| 238 | cmp expect current |
| 239 | } |
| 240 | |
| 241 | test_expect_success 'use packed objects' ' |
| 242 | check_use_objects test-1-${packname_1} |
| 243 | ' |
| 244 | |
| 245 | test_expect_success 'use packed deltified (REF_DELTA) objects' ' |
| 246 | check_use_objects test-2-${packname_2} |
| 247 | ' |
| 248 | |
| 249 | test_expect_success 'use packed deltified (OFS_DELTA) objects' ' |
| 250 | check_use_objects test-3-${packname_3} |
| 251 | ' |
| 252 | |
| 253 | test_expect_success 'survive missing objects/pack directory' ' |
| 254 | ( |
| 255 | rm -fr missing-pack && |
| 256 | mkdir missing-pack && |
| 257 | cd missing-pack && |
| 258 | git init && |
| 259 | GOP=.git/objects/pack && |
| 260 | rm -fr $GOP && |
| 261 | git index-pack --stdin --keep=test <../test-3-${packname_3}.pack && |
| 262 | test -f $GOP/pack-${packname_3}.pack && |
| 263 | cmp $GOP/pack-${packname_3}.pack ../test-3-${packname_3}.pack && |
| 264 | test -f $GOP/pack-${packname_3}.idx && |
| 265 | cmp $GOP/pack-${packname_3}.idx ../test-3-${packname_3}.idx && |
| 266 | test -f $GOP/pack-${packname_3}.keep |
| 267 | ) |
| 268 | ' |
| 269 | |
| 270 | test_expect_success 'verify pack' ' |
| 271 | git verify-pack test-1-${packname_1}.idx \ |
| 272 | test-2-${packname_2}.idx \ |
| 273 | test-3-${packname_3}.idx |
| 274 | ' |
| 275 | |
| 276 | test_expect_success 'verify pack -v' ' |
| 277 | git verify-pack -v test-1-${packname_1}.idx \ |
| 278 | test-2-${packname_2}.idx \ |
| 279 | test-3-${packname_3}.idx |
| 280 | ' |
| 281 | |
| 282 | test_expect_success 'verify-pack catches mismatched .idx and .pack files' ' |
| 283 | cat test-1-${packname_1}.idx >test-3.idx && |
| 284 | cat test-2-${packname_2}.pack >test-3.pack && |
| 285 | if git verify-pack test-3.idx |
| 286 | then false |
| 287 | else :; |
| 288 | fi |
| 289 | ' |
| 290 | |
| 291 | test_expect_success 'verify-pack catches a corrupted pack signature' ' |
| 292 | cat test-1-${packname_1}.pack >test-3.pack && |
| 293 | echo | dd of=test-3.pack count=1 bs=1 conv=notrunc seek=2 && |
| 294 | if git verify-pack test-3.idx |
| 295 | then false |
| 296 | else :; |
| 297 | fi |
| 298 | ' |
| 299 | |
| 300 | test_expect_success 'verify-pack catches a corrupted pack version' ' |
| 301 | cat test-1-${packname_1}.pack >test-3.pack && |
| 302 | echo | dd of=test-3.pack count=1 bs=1 conv=notrunc seek=7 && |
| 303 | if git verify-pack test-3.idx |
| 304 | then false |
| 305 | else :; |
| 306 | fi |
| 307 | ' |
| 308 | |
| 309 | test_expect_success 'verify-pack catches a corrupted type/size of the 1st packed object data' ' |
| 310 | cat test-1-${packname_1}.pack >test-3.pack && |
| 311 | echo | dd of=test-3.pack count=1 bs=1 conv=notrunc seek=12 && |
| 312 | if git verify-pack test-3.idx |
| 313 | then false |
| 314 | else :; |
| 315 | fi |
| 316 | ' |
| 317 | |
| 318 | test_expect_success 'verify-pack catches a corrupted sum of the index file itself' ' |
| 319 | l=$(wc -c <test-3.idx) && |
| 320 | l=$(expr $l - 20) && |
| 321 | cat test-1-${packname_1}.pack >test-3.pack && |
| 322 | printf "%20s" "" | dd of=test-3.idx count=20 bs=1 conv=notrunc seek=$l && |
| 323 | if git verify-pack test-3.pack |
| 324 | then false |
| 325 | else :; |
| 326 | fi |
| 327 | ' |
| 328 | |
| 329 | test_expect_success 'build pack index for an existing pack' ' |
| 330 | cat test-1-${packname_1}.pack >test-3.pack && |
| 331 | git index-pack -o tmp.idx test-3.pack && |
| 332 | cmp tmp.idx test-1-${packname_1}.idx && |
| 333 | |
| 334 | git index-pack test-3.pack && |
| 335 | cmp test-3.idx test-1-${packname_1}.idx && |
| 336 | |
| 337 | cat test-2-${packname_2}.pack >test-3.pack && |
| 338 | git index-pack -o tmp.idx test-2-${packname_2}.pack && |
| 339 | cmp tmp.idx test-2-${packname_2}.idx && |
| 340 | |
| 341 | git index-pack test-3.pack && |
| 342 | cmp test-3.idx test-2-${packname_2}.idx && |
| 343 | |
| 344 | cat test-3-${packname_3}.pack >test-3.pack && |
| 345 | git index-pack -o tmp.idx test-3-${packname_3}.pack && |
| 346 | cmp tmp.idx test-3-${packname_3}.idx && |
| 347 | |
| 348 | git index-pack test-3.pack && |
| 349 | cmp test-3.idx test-3-${packname_3}.idx && |
| 350 | |
| 351 | cat test-1-${packname_1}.pack >test-4.pack && |
| 352 | rm -f test-4.keep && |
| 353 | git index-pack --keep=why test-4.pack && |
| 354 | cmp test-1-${packname_1}.idx test-4.idx && |
| 355 | test -f test-4.keep && |
| 356 | |
| 357 | : |
| 358 | ' |
| 359 | |
| 360 | test_expect_success 'unpacking with --strict' ' |
| 361 | |
| 362 | for j in a b c d e f g |
| 363 | do |
| 364 | for i in 0 1 2 3 4 5 6 7 8 9 |
| 365 | do |
| 366 | o=$(echo $j$i | git hash-object -w --stdin) && |
| 367 | echo "100644 $o 0 $j$i" || return 1 |
| 368 | done |
| 369 | done >LIST && |
| 370 | rm -f .git/index && |
| 371 | git update-index --index-info <LIST && |
| 372 | LIST=$(git write-tree) && |
| 373 | rm -f .git/index && |
| 374 | head -n 10 LIST | git update-index --index-info && |
| 375 | LI=$(git write-tree) && |
| 376 | rm -f .git/index && |
| 377 | tail -n 10 LIST | git update-index --index-info && |
| 378 | ST=$(git write-tree) && |
| 379 | git rev-list --objects "$LIST" "$LI" "$ST" >actual && |
| 380 | PACK5=$( git pack-objects test-5 <actual ) && |
| 381 | PACK6=$( test_write_lines "$LIST" "$LI" "$ST" | git pack-objects test-6 ) && |
| 382 | test_create_repo test-5 && |
| 383 | ( |
| 384 | cd test-5 && |
| 385 | git unpack-objects --strict <../test-5-$PACK5.pack && |
| 386 | git ls-tree -r $LIST && |
| 387 | git ls-tree -r $LI && |
| 388 | git ls-tree -r $ST |
| 389 | ) && |
| 390 | test_create_repo test-6 && |
| 391 | ( |
| 392 | # tree-only into empty repo -- many unreachables |
| 393 | cd test-6 && |
| 394 | test_must_fail git unpack-objects --strict <../test-6-$PACK6.pack |
| 395 | ) && |
| 396 | ( |
| 397 | # already populated -- no unreachables |
| 398 | cd test-5 && |
| 399 | git unpack-objects --strict <../test-6-$PACK6.pack |
| 400 | ) |
| 401 | ' |
| 402 | |
| 403 | test_expect_success 'index-pack with --strict' ' |
| 404 | |
| 405 | for j in a b c d e f g |
| 406 | do |
| 407 | for i in 0 1 2 3 4 5 6 7 8 9 |
| 408 | do |
| 409 | o=$(echo $j$i | git hash-object -w --stdin) && |
| 410 | echo "100644 $o 0 $j$i" || return 1 |
| 411 | done |
| 412 | done >LIST && |
| 413 | rm -f .git/index && |
| 414 | git update-index --index-info <LIST && |
| 415 | LIST=$(git write-tree) && |
| 416 | rm -f .git/index && |
| 417 | head -n 10 LIST | git update-index --index-info && |
| 418 | LI=$(git write-tree) && |
| 419 | rm -f .git/index && |
| 420 | tail -n 10 LIST | git update-index --index-info && |
| 421 | ST=$(git write-tree) && |
| 422 | git rev-list --objects "$LIST" "$LI" "$ST" >actual && |
| 423 | PACK5=$( git pack-objects test-5 <actual ) && |
| 424 | PACK6=$( test_write_lines "$LIST" "$LI" "$ST" | git pack-objects test-6 ) && |
| 425 | test_create_repo test-7 && |
| 426 | ( |
| 427 | cd test-7 && |
| 428 | git index-pack --strict --stdin <../test-5-$PACK5.pack && |
| 429 | git ls-tree -r $LIST && |
| 430 | git ls-tree -r $LI && |
| 431 | git ls-tree -r $ST |
| 432 | ) && |
| 433 | test_create_repo test-8 && |
| 434 | ( |
| 435 | # tree-only into empty repo -- many unreachables |
| 436 | cd test-8 && |
| 437 | test_must_fail git index-pack --strict --stdin <../test-6-$PACK6.pack |
| 438 | ) && |
| 439 | ( |
| 440 | # already populated -- no unreachables |
| 441 | cd test-7 && |
| 442 | git index-pack --strict --stdin <../test-6-$PACK6.pack |
| 443 | ) |
| 444 | ' |
| 445 | |
| 446 | test_expect_success 'setup for --strict and --fsck-objects downgrading fsck msgs' ' |
| 447 | git init strict && |
| 448 | ( |
| 449 | cd strict && |
| 450 | test_commit first hello && |
| 451 | cat >commit <<-EOF && |
| 452 | tree $(git rev-parse HEAD^{tree}) |
| 453 | parent $(git rev-parse HEAD) |
| 454 | author A U Thor |
| 455 | committer A U Thor |
| 456 | |
| 457 | commit: this is a commit with bad emails |
| 458 | |
| 459 | EOF |
| 460 | git hash-object --literally -t commit -w --stdin <commit >commit_list && |
| 461 | git pack-objects test <commit_list >pack-name |
| 462 | ) |
| 463 | ' |
| 464 | |
| 465 | test_with_bad_commit () { |
| 466 | must_fail_arg="$1" && |
| 467 | must_pass_arg="$2" && |
| 468 | ( |
| 469 | cd strict && |
| 470 | test_must_fail git index-pack "$must_fail_arg" "test-$(cat pack-name).pack" && |
| 471 | git index-pack "$must_pass_arg" "test-$(cat pack-name).pack" |
| 472 | ) |
| 473 | } |
| 474 | |
| 475 | test_expect_success 'index-pack with --strict downgrading fsck msgs' ' |
| 476 | test_with_bad_commit --strict --strict="missingEmail=ignore" |
| 477 | ' |
| 478 | |
| 479 | test_expect_success 'index-pack with --fsck-objects downgrading fsck msgs' ' |
| 480 | test_with_bad_commit --fsck-objects --fsck-objects="missingEmail=ignore" |
| 481 | ' |
| 482 | |
| 483 | test_expect_success 'cleanup for --strict and --fsck-objects downgrading fsck msgs' ' |
| 484 | rm -rf strict |
| 485 | ' |
| 486 | |
| 487 | test_expect_success 'honor pack.packSizeLimit' ' |
| 488 | git config pack.packSizeLimit 3m && |
| 489 | packname_10=$(git pack-objects test-10 <obj-list) && |
| 490 | test 2 = $(ls test-10-*.pack | wc -l) |
| 491 | ' |
| 492 | |
| 493 | test_expect_success 'verify resulting packs' ' |
| 494 | git verify-pack test-10-*.pack |
| 495 | ' |
| 496 | |
| 497 | test_expect_success 'tolerate packsizelimit smaller than biggest object' ' |
| 498 | git config pack.packSizeLimit 1 && |
| 499 | packname_11=$(git pack-objects test-11 <obj-list) && |
| 500 | test 5 = $(ls test-11-*.pack | wc -l) |
| 501 | ' |
| 502 | |
| 503 | test_expect_success 'verify resulting packs' ' |
| 504 | git verify-pack test-11-*.pack |
| 505 | ' |
| 506 | |
| 507 | test_expect_success 'set up pack for non-repo tests' ' |
| 508 | # make sure we have a pack with no matching index file |
| 509 | cp test-1-*.pack foo.pack |
| 510 | ' |
| 511 | |
| 512 | test_expect_success 'index-pack --stdin complains of non-repo' ' |
| 513 | nongit test_must_fail git index-pack --object-format=$(test_oid algo) --stdin <foo.pack && |
| 514 | test_path_is_missing non-repo/.git |
| 515 | ' |
| 516 | |
| 517 | test_expect_success 'index-pack <pack> works in non-repo' ' |
| 518 | nongit git index-pack --object-format=$(test_oid algo) ../foo.pack && |
| 519 | test_path_is_file foo.idx |
| 520 | ' |
| 521 | |
| 522 | test_expect_success 'index-pack --strict <pack> works in non-repo' ' |
| 523 | rm -f foo.idx && |
| 524 | nongit git index-pack --strict --object-format=$(test_oid algo) ../foo.pack && |
| 525 | test_path_is_file foo.idx |
| 526 | ' |
| 527 | |
| 528 | test_expect_success DEFAULT_HASH_ALGORITHM 'show-index works OK outside a repository' ' |
| 529 | nongit git show-index <foo.idx |
| 530 | ' |
| 531 | |
| 532 | for hash in sha1 sha256 |
| 533 | do |
| 534 | test_expect_success 'show-index works OK outside a repository with hash algo passed in via --object-format' ' |
| 535 | test_when_finished "rm -rf explicit-hash-$hash" && |
| 536 | git init --object-format=$hash explicit-hash-$hash && |
| 537 | test_commit -C explicit-hash-$hash one && |
| 538 | git -C explicit-hash-$hash rev-parse one >in && |
| 539 | git -C explicit-hash-$hash pack-objects explicit-hash-$hash <in && |
| 540 | idx=$(echo explicit-hash-$hash/explicit-hash-$hash*.idx) && |
| 541 | nongit git show-index --object-format=$hash <"$idx" >actual && |
| 542 | test_line_count = 1 actual |
| 543 | ' |
| 544 | done |
| 545 | |
| 546 | test_expect_success !PTHREADS,!FAIL_PREREQS \ |
| 547 | 'index-pack --threads=N or pack.threads=N warns when no pthreads' ' |
| 548 | test_must_fail git index-pack --threads=2 2>err && |
| 549 | grep ^warning: err >warnings && |
| 550 | test_line_count = 1 warnings && |
| 551 | grep -F "no threads support, ignoring --threads=2" err && |
| 552 | |
| 553 | test_must_fail git -c pack.threads=2 index-pack 2>err && |
| 554 | grep ^warning: err >warnings && |
| 555 | test_line_count = 1 warnings && |
| 556 | grep -F "no threads support, ignoring pack.threads" err && |
| 557 | |
| 558 | test_must_fail git -c pack.threads=2 index-pack --threads=4 2>err && |
| 559 | grep ^warning: err >warnings && |
| 560 | test_line_count = 2 warnings && |
| 561 | grep -F "no threads support, ignoring --threads=4" err && |
| 562 | grep -F "no threads support, ignoring pack.threads" err |
| 563 | ' |
| 564 | |
| 565 | test_expect_success !PTHREADS,!FAIL_PREREQS \ |
| 566 | 'pack-objects --threads=N or pack.threads=N warns when no pthreads' ' |
| 567 | git pack-objects --threads=2 --stdout --all </dev/null >/dev/null 2>err && |
| 568 | grep ^warning: err >warnings && |
| 569 | test_line_count = 1 warnings && |
| 570 | grep -F "no threads support, ignoring --threads" err && |
| 571 | |
| 572 | git -c pack.threads=2 pack-objects --stdout --all </dev/null >/dev/null 2>err && |
| 573 | grep ^warning: err >warnings && |
| 574 | test_line_count = 1 warnings && |
| 575 | grep -F "no threads support, ignoring pack.threads" err && |
| 576 | |
| 577 | git -c pack.threads=2 pack-objects --threads=4 --stdout --all </dev/null >/dev/null 2>err && |
| 578 | grep ^warning: err >warnings && |
| 579 | test_line_count = 2 warnings && |
| 580 | grep -F "no threads support, ignoring --threads" err && |
| 581 | grep -F "no threads support, ignoring pack.threads" err |
| 582 | ' |
| 583 | |
| 584 | test_expect_success 'pack-objects in too-many-packs mode' ' |
| 585 | GIT_TEST_FULL_IN_PACK_ARRAY=1 git repack -ad && |
| 586 | git fsck |
| 587 | ' |
| 588 | |
| 589 | test_expect_success 'setup: fake a SHA1 hash collision' ' |
| 590 | git init corrupt && |
| 591 | ( |
| 592 | cd corrupt && |
| 593 | long_a=$(git hash-object -w ../a | sed -e "s!^..!&/!") && |
| 594 | long_b=$(git hash-object -w ../b | sed -e "s!^..!&/!") && |
| 595 | test -f .git/objects/$long_b && |
| 596 | cp -f .git/objects/$long_a \ |
| 597 | .git/objects/$long_b |
| 598 | ) |
| 599 | ' |
| 600 | |
| 601 | test_expect_success 'make sure index-pack detects the SHA1 collision' ' |
| 602 | ( |
| 603 | cd corrupt && |
| 604 | test_must_fail git index-pack -o ../bad.idx ../test-3.pack 2>msg && |
| 605 | test_grep "SHA1 COLLISION FOUND" msg |
| 606 | ) |
| 607 | ' |
| 608 | |
| 609 | test_expect_success 'make sure index-pack detects the SHA1 collision (large blobs)' ' |
| 610 | ( |
| 611 | cd corrupt && |
| 612 | test_must_fail git -c core.bigfilethreshold=1 index-pack -o ../bad.idx ../test-3.pack 2>msg && |
| 613 | test_grep "SHA1 COLLISION FOUND" msg |
| 614 | ) |
| 615 | ' |
| 616 | |
| 617 | test_expect_success 'prefetch objects' ' |
| 618 | rm -rf server client && |
| 619 | |
| 620 | git init server && |
| 621 | test_config -C server uploadpack.allowanysha1inwant 1 && |
| 622 | test_config -C server uploadpack.allowfilter 1 && |
| 623 | test_config -C server protocol.version 2 && |
| 624 | |
| 625 | echo one >server/one && |
| 626 | git -C server add one && |
| 627 | git -C server commit -m one && |
| 628 | git -C server branch one_branch && |
| 629 | |
| 630 | echo two_a >server/two_a && |
| 631 | echo two_b >server/two_b && |
| 632 | git -C server add two_a two_b && |
| 633 | git -C server commit -m two && |
| 634 | |
| 635 | echo three >server/three && |
| 636 | git -C server add three && |
| 637 | git -C server commit -m three && |
| 638 | git -C server branch three_branch && |
| 639 | |
| 640 | # Clone, fetch "two" with blobs excluded, and re-push it. This requires |
| 641 | # the client to have the blobs of "two" - verify that these are |
| 642 | # prefetched in one batch. |
| 643 | git clone --filter=blob:none --single-branch -b one_branch \ |
| 644 | "file://$(pwd)/server" client && |
| 645 | test_config -C client protocol.version 2 && |
| 646 | TWO=$(git -C server rev-parse three_branch^) && |
| 647 | git -C client fetch --filter=blob:none origin "$TWO" && |
| 648 | GIT_TRACE_PACKET=$(pwd)/trace git -C client push origin "$TWO":refs/heads/two_branch && |
| 649 | grep "fetch> done" trace >donelines && |
| 650 | test_line_count = 1 donelines |
| 651 | ' |
| 652 | |
| 653 | for hash in sha1 sha256 |
| 654 | do |
| 655 | test_expect_success "verify-pack with $hash packfile" ' |
| 656 | test_when_finished "rm -rf repo" && |
| 657 | git init --object-format=$hash repo && |
| 658 | test_commit -C repo initial && |
| 659 | git -C repo repack -ad && |
| 660 | git -C repo verify-pack "$(pwd)"/repo/.git/objects/pack/*.idx && |
| 661 | if test $hash = $GIT_TEST_BUILTIN_HASH |
| 662 | then |
| 663 | nongit git verify-pack "$(pwd)"/repo/.git/objects/pack/*.idx |
| 664 | else |
| 665 | # We have no way to identify the hash used by packfiles |
| 666 | # or indices, so we always fall back to SHA1. |
| 667 | nongit test_must_fail git verify-pack "$(pwd)"/repo/.git/objects/pack/*.idx && |
| 668 | # But with an explicit object format we should succeed. |
| 669 | nongit git verify-pack --object-format=$hash "$(pwd)"/repo/.git/objects/pack/*.idx |
| 670 | fi |
| 671 | ' |
| 672 | |
| 673 | test_expect_success "index-pack outside of a $hash repository" ' |
| 674 | test_when_finished "rm -rf repo" && |
| 675 | git init --object-format=$hash repo && |
| 676 | test_commit -C repo initial && |
| 677 | git -C repo repack -ad && |
| 678 | git -C repo index-pack --verify "$(pwd)"/repo/.git/objects/pack/*.pack && |
| 679 | if test $hash = $GIT_TEST_BUILTIN_HASH |
| 680 | then |
| 681 | nongit git index-pack --verify "$(pwd)"/repo/.git/objects/pack/*.pack |
| 682 | else |
| 683 | # We have no way to identify the hash used by packfiles |
| 684 | # or indices, so we always fall back to SHA1. |
| 685 | nongit test_must_fail git index-pack --verify "$(pwd)"/repo/.git/objects/pack/*.pack 2>err && |
| 686 | # But with an explicit object format we should succeed. |
| 687 | nongit git index-pack --object-format=$hash --verify "$(pwd)"/repo/.git/objects/pack/*.pack |
| 688 | fi |
| 689 | ' |
| 690 | done |
| 691 | |
| 692 | test_expect_success 'valid and invalid --name-hash-versions' ' |
| 693 | sane_unset GIT_TEST_NAME_HASH_VERSION && |
| 694 | |
| 695 | # Valid values are hard to verify other than "do not fail". |
| 696 | # Performance tests will be more valuable to validate these versions. |
| 697 | # Negative values are converted to version 1. |
| 698 | for value in -1 1 2 |
| 699 | do |
| 700 | git pack-objects base --all --name-hash-version=$value || return 1 |
| 701 | done && |
| 702 | |
| 703 | # Invalid values have clear post-conditions. |
| 704 | for value in 0 3 |
| 705 | do |
| 706 | test_must_fail git pack-objects base --all --name-hash-version=$value 2>err && |
| 707 | test_grep "invalid --name-hash-version option" err || return 1 |
| 708 | done |
| 709 | ' |
| 710 | |
| 711 | # The following test is not necessarily a permanent choice, but since we do not |
| 712 | # have a "name hash version" bit in the .bitmap file format, we cannot write the |
| 713 | # hash values into the .bitmap file without risking breakage later. |
| 714 | # |
| 715 | # TODO: Make these compatible in the future and replace this test with the |
| 716 | # expected behavior when both are specified. |
| 717 | test_expect_success '--name-hash-version=2 and --write-bitmap-index are incompatible' ' |
| 718 | git pack-objects base --all --name-hash-version=2 --write-bitmap-index 2>err && |
| 719 | test_grep "currently, --write-bitmap-index requires --name-hash-version=1" err && |
| 720 | |
| 721 | # --stdout option silently removes --write-bitmap-index |
| 722 | git pack-objects --stdout --all --name-hash-version=2 --write-bitmap-index >out 2>err && |
| 723 | ! test_grep "currently, --write-bitmap-index requires --name-hash-version=1" err |
| 724 | ' |
| 725 | |
| 726 | test_expect_success '--path-walk pack everything' ' |
| 727 | git -C server rev-parse HEAD >in && |
| 728 | GIT_PROGRESS_DELAY=0 git -C server pack-objects \ |
| 729 | --stdout --revs --path-walk --progress <in >out.pack 2>err && |
| 730 | grep "Compressing objects by path" err && |
| 731 | git -C server index-pack --stdin <out.pack |
| 732 | ' |
| 733 | |
| 734 | test_expect_success '--path-walk thin pack' ' |
| 735 | cat >in <<-EOF && |
| 736 | $(git -C server rev-parse HEAD) |
| 737 | ^$(git -C server rev-parse HEAD~2) |
| 738 | EOF |
| 739 | GIT_PROGRESS_DELAY=0 git -C server pack-objects \ |
| 740 | --thin --stdout --revs --path-walk --progress <in >out.pack 2>err && |
| 741 | grep "Compressing objects by path" err && |
| 742 | git -C server index-pack --fix-thin --stdin <out.pack |
| 743 | ' |
| 744 | |
| 745 | test_done |