index-pack: prefetch missing REF_DELTA bases
authorJonathan Tan <jonathantanmy@google.com>
Tue, 14 May 2019 21:10:55 +0000 (14:10 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 15 May 2019 02:01:40 +0000 (11:01 +0900)
commit8a30a1efd11bcfb7b0f5b8543492a09fc495ae60
tree3a0c75f8ffc53b4ffda38532e3edcbeb431f1202
parent385d1bfd7ad5d49783a3956bba19d9feea9955b6
index-pack: prefetch missing REF_DELTA bases

When fetching, the client sends "have" commit IDs indicating that the
server does not need to send any object referenced by those commits,
reducing network I/O. When the client is a partial clone, the client
still sends "have"s in this way, even if it does not have every object
referenced by a commit it sent as "have".

If a server omits such an object, it is fine: the client could lazily
fetch that object before this fetch, and it can still do so after.

The issue is when the server sends a thin pack containing an object that
is a REF_DELTA against such a missing object: index-pack fails to fix
the thin pack. When support for lazily fetching missing objects was
added in 8b4c0103a9 ("sha1_file: support lazily fetching missing
objects", 2017-12-08), support in index-pack was turned off in the
belief that it accesses the repo only to do hash collision checks.
However, this is not true: it also needs to access the repo to resolve
REF_DELTA bases.

Support for lazy fetching should still generally be turned off in
index-pack because it is used as part of the lazy fetching process
itself (if not, infinite loops may occur), but we do need to fetch the
REF_DELTA bases. (When fetching REF_DELTA bases, it is unlikely that
those are REF_DELTA themselves, because we do not send "have" when
making such fetches.)

To resolve this, prefetch all missing REF_DELTA bases before attempting
to resolve them. This both ensures that all bases are attempted to be
fetched, and ensures that we make only one request per index-pack
invocation, and not one request per missing object.

Signed-off-by: Jonathan Tan <jonathantanmy@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/index-pack.c
t/t5616-partial-clone.sh