diff options
author | Junio C Hamano <gitster@pobox.com> | 2013-06-23 14:53:20 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2013-06-23 14:53:20 -0700 |
commit | ee64e345b1ac13cbb9c6a2343453fa3fc798367a (patch) | |
tree | f410dbf23e0cb15a71e853358b8610b470360121 | |
parent | 23983a473dc889cfba8a64f040942298a6f5f99a (diff) | |
parent | 1ee886c1f08f4dd672a342b7811191b02291a597 (diff) | |
download | git-ee64e345b1ac13cbb9c6a2343453fa3fc798367a.tar.gz |
Merge branch 'jk/unpack-entry-fallback-to-another'
* jk/unpack-entry-fallback-to-another:
unpack_entry: do not die when we fail to apply a delta
t5303: drop "count=1" from corruption dd
-rw-r--r-- | sha1_file.c | 11 | ||||
-rwxr-xr-x | t/t5303-pack-corruption-resilience.sh | 29 |
2 files changed, 38 insertions, 2 deletions
diff --git a/sha1_file.c b/sha1_file.c index 16f08d475c..0af19c00f1 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -2145,8 +2145,17 @@ void *unpack_entry(struct packed_git *p, off_t obj_offset, data = patch_delta(base, base_size, delta_data, delta_size, &size); + + /* + * We could not apply the delta; warn the user, but keep going. + * Our failure will be noticed either in the next iteration of + * the loop, or if this is the final delta, in the caller when + * we return NULL. Those code paths will take care of making + * a more explicit warning and retrying with another copy of + * the object. + */ if (!data) - die("failed to apply delta"); + error("failed to apply delta"); free(delta_data); } diff --git a/t/t5303-pack-corruption-resilience.sh b/t/t5303-pack-corruption-resilience.sh index 5b1250f0d2..35926debe3 100755 --- a/t/t5303-pack-corruption-resilience.sh +++ b/t/t5303-pack-corruption-resilience.sh @@ -51,7 +51,7 @@ do_corrupt_object() { ofs=`git show-index < ${pack}.idx | grep $1 | cut -f1 -d" "` && ofs=$(($ofs + $2)) && chmod +w ${pack}.pack && - dd of=${pack}.pack count=1 bs=1 conv=notrunc seek=$ofs && + dd of=${pack}.pack bs=1 conv=notrunc seek=$ofs && test_must_fail git verify-pack ${pack}.pack } @@ -276,6 +276,33 @@ test_expect_success \ git cat-file blob $blob_3 > /dev/null' test_expect_success \ + 'corruption of delta base reference pointing to wrong object' \ + 'create_new_pack --delta-base-offset && + git prune-packed && + printf "\220\033" | do_corrupt_object $blob_3 2 && + git cat-file blob $blob_1 >/dev/null && + git cat-file blob $blob_2 >/dev/null && + test_must_fail git cat-file blob $blob_3 >/dev/null' + +test_expect_success \ + '... but having a loose copy allows for full recovery' \ + 'mv ${pack}.idx tmp && + git hash-object -t blob -w file_3 && + mv tmp ${pack}.idx && + git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null' + +test_expect_success \ + '... and then a repack "clears" the corruption' \ + 'do_repack --delta-base-offset --no-reuse-delta && + git prune-packed && + git verify-pack ${pack}.pack && + git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null' + +test_expect_success \ 'corrupting header to have too small output buffer fails unpack' \ 'create_new_pack && git prune-packed && |