upload-pack: do not lazy-fetch "have" objects

When upload-pack receives a request containing "have" hashes, it (among
other things) checks if the served repository has the corresponding
objects. However, it does not do so with the
OBJECT_INFO_SKIP_FETCH_OBJECT flag, so if serving a partial clone, a
lazy fetch will be triggered first.

This was discovered at $DAYJOB when a user fetched from a partial clone
(into another partial clone - although this would also happen if the
repo to be fetched into is not a partial clone).

Therefore, whenever "have" hashes are checked for existence, pass the
OBJECT_INFO_SKIP_FETCH_OBJECT flag. Also add the OBJECT_INFO_QUICK flag
to improve performance, as it is typical that such objects do not exist
in the serving repo, and the consequences of a false negative are minor
(usually, a slightly larger pack sent).

Signed-off-by: Jonathan Tan <jonathantanmy@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Jonathan Tan
2020-07-16 11:09:50 -07:00
committed by Junio C Hamano
parent bd42bbe1a4
commit 77aa0941ce
2 changed files with 42 additions and 2 deletions

View File

@ -482,7 +482,8 @@ static int got_oid(struct upload_pack_data *data,
{
if (get_oid_hex(hex, oid))
die("git upload-pack: expected SHA1 object, got '%s'", hex);
if (!has_object_file(oid))
if (!has_object_file_with_flags(oid,
OBJECT_INFO_QUICK | OBJECT_INFO_SKIP_FETCH_OBJECT))
return -1;
return do_got_oid(data, oid);
}
@ -1423,7 +1424,8 @@ static int process_haves(struct upload_pack_data *data, struct oid_array *common
for (i = 0; i < data->haves.nr; i++) {
const struct object_id *oid = &data->haves.oid[i];
if (!has_object_file(oid))
if (!has_object_file_with_flags(oid,
OBJECT_INFO_QUICK | OBJECT_INFO_SKIP_FETCH_OBJECT))
continue;
oid_array_append(common, oid);