mirror of
https://github.com/git/git
synced 2024-08-24 18:26:02 +00:00
index-pack: detect local corruption in collision check
When we notice that we have a local copy of an incoming object, we compare the two objects to make sure we haven't found a collision. Before we get to the actual object bytes, though, we compare the type and size from sha1_object_info(). If our local object is corrupted, then the type will be OBJ_BAD, which obviously will not match the incoming type, and we'll report "SHA1 COLLISION FOUND" (with capital letters and everything). This is confusing, as the problem is not a collision but rather local corruption. We should report that instead (just like we do if reading the rest of the object content fails a few lines later). Note that we _could_ just ignore the error and mark it as a non-collision. That would let you "git fetch" to replace a corrupted object. But it's not a very reliable method for repairing a repository. The earlier want/have negotiation tries to get the other side to omit objects we already have, and it would not realize that we are "missing" this corrupted object. So we're better off complaining loudly when we see corruption, and letting the user take more drastic measures to repair (like making a full clone elsewhere and copying the pack into place). Note that the test sets transfer.unpackLimit in the receiving repository so that we use index-pack (which is what does the collision check). Normally for such a small push we'd use unpack-objects, which would simply try to write the loose object, and discard the new one when we see that there's already an old one. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
93cff9a978
commit
51054177b3
|
@ -809,6 +809,8 @@ static void sha1_object(const void *data, struct object_entry *obj_entry,
|
||||||
unsigned long has_size;
|
unsigned long has_size;
|
||||||
read_lock();
|
read_lock();
|
||||||
has_type = sha1_object_info(sha1, &has_size);
|
has_type = sha1_object_info(sha1, &has_size);
|
||||||
|
if (has_type < 0)
|
||||||
|
die(_("cannot read existing object info %s"), sha1_to_hex(sha1));
|
||||||
if (has_type != type || has_size != size)
|
if (has_type != type || has_size != size)
|
||||||
die(_("SHA1 COLLISION FOUND WITH %s !"), sha1_to_hex(sha1));
|
die(_("SHA1 COLLISION FOUND WITH %s !"), sha1_to_hex(sha1));
|
||||||
has_data = read_sha1_file(sha1, &has_type, &has_size);
|
has_data = read_sha1_file(sha1, &has_type, &has_size);
|
||||||
|
|
|
@ -21,6 +21,14 @@ test_expect_success 'setup corrupt repo' '
|
||||||
cd bit-error &&
|
cd bit-error &&
|
||||||
test_commit content &&
|
test_commit content &&
|
||||||
corrupt_byte HEAD:content.t 10
|
corrupt_byte HEAD:content.t 10
|
||||||
|
) &&
|
||||||
|
git init no-bit-error &&
|
||||||
|
(
|
||||||
|
# distinct commit from bit-error, but containing a
|
||||||
|
# non-corrupted version of the same blob
|
||||||
|
cd no-bit-error &&
|
||||||
|
test_tick &&
|
||||||
|
test_commit content
|
||||||
)
|
)
|
||||||
'
|
'
|
||||||
|
|
||||||
|
@ -108,4 +116,13 @@ test_expect_failure 'clone --local detects misnamed objects' '
|
||||||
test_must_fail git clone --local misnamed misnamed-checkout
|
test_must_fail git clone --local misnamed misnamed-checkout
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'fetch into corrupted repo with index-pack' '
|
||||||
|
(
|
||||||
|
cd bit-error &&
|
||||||
|
test_must_fail git -c transfer.unpackLimit=1 \
|
||||||
|
fetch ../no-bit-error 2>stderr &&
|
||||||
|
test_i18ngrep ! -i collision stderr
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
|
Loading…
Reference in a new issue