sha1-lookup: handle duplicate keys with GIT_USE_LOOKUP
commit171bdaca698a69c5a43067e4d6d81abfc50f17d6
authorJeff King <peff@peff.net>
Sat, 24 Aug 2013 00:02:25 +0000 (23 20:02 -0400)
committerJunio C Hamano <gitster@pobox.com>
Sun, 25 Aug 2013 05:31:20 +0000 (24 22:31 -0700)
tree367d62dceb3a3e2a96b6f15c4557925cedfe5f51
parent54c93cb4afc932ab125a59464bb52e04f9c36575
sha1-lookup: handle duplicate keys with GIT_USE_LOOKUP

The sha1_entry_pos function tries to be smart about
selecting the middle of a range for its binary search by
looking at the value differences between the "lo" and "hi"
constraints. However, it is unable to cope with entries with
duplicate keys in the sorted list.

We may hit a point in the search where both our "lo" and
"hi" point to the same key. In this case, the range of
values between our endpoints is 0, and trying to scale the
difference between our key and the endpoints over that range
is undefined (i.e., divide by zero). The current code
catches this with an "assert(lov < hiv)".

Moreover, after seeing that the first 20 byte of the key are
the same, we will try to establish a value from the 21st
byte. Which is nonsensical.

Instead, we can detect the case that we are in a run of
duplicates, and simply do a final comparison against any one
of them (since they are all the same, it does not matter
which). If the keys match, we have found our entry (or one
of them, anyway).  If not, then we know that we do not need
to look further, as we must be in a run of the duplicate
key.

Signed-off-by: Jeff King <peff@peff.net>
Acked-by: Nicolas Pitre <nico@fluxnic.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
sha1-lookup.c
t/lib-pack.sh [new file with mode: 0644]
t/t5308-pack-detect-duplicates.sh [new file with mode: 0755]