index-pack: detect local corruption in collision check
commit51054177b312ce0795f2866d4c3aed246eeccea9
authorJeff King <peff@peff.net>
Sat, 1 Apr 2017 08:09:32 +0000 (1 04:09 -0400)
committerJunio C Hamano <gitster@pobox.com>
Sat, 1 Apr 2017 17:48:11 +0000 (1 10:48 -0700)
tree8d1b8e934344fb9013b6653cf7818c9111d044e4
parent93cff9a978e1c177ac3e889867004a56773301b2
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>
builtin/index-pack.c
t/t1060-object-corruption.sh