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:
parent
bd42bbe1a4
commit
77aa0941ce
@ -422,6 +422,44 @@ test_expect_success 'single-branch tag following respects partial clone' '
|
||||
test_must_fail git -C single rev-parse --verify refs/tags/C
|
||||
'
|
||||
|
||||
test_expect_success 'fetch from a partial clone, protocol v0' '
|
||||
rm -rf server client trace &&
|
||||
|
||||
# Pretend that the server is a partial clone
|
||||
git init server &&
|
||||
git -C server remote add a_remote "file://$(pwd)/" &&
|
||||
test_config -C server core.repositoryformatversion 1 &&
|
||||
test_config -C server extensions.partialclone a_remote &&
|
||||
test_config -C server protocol.version 0 &&
|
||||
test_commit -C server foo &&
|
||||
|
||||
# Fetch from the server
|
||||
git init client &&
|
||||
test_config -C client protocol.version 0 &&
|
||||
test_commit -C client bar &&
|
||||
GIT_TRACE_PACKET="$(pwd)/trace" git -C client fetch "file://$(pwd)/server" &&
|
||||
! grep "version 2" trace
|
||||
'
|
||||
|
||||
test_expect_success 'fetch from a partial clone, protocol v2' '
|
||||
rm -rf server client trace &&
|
||||
|
||||
# Pretend that the server is a partial clone
|
||||
git init server &&
|
||||
git -C server remote add a_remote "file://$(pwd)/" &&
|
||||
test_config -C server core.repositoryformatversion 1 &&
|
||||
test_config -C server extensions.partialclone a_remote &&
|
||||
test_config -C server protocol.version 2 &&
|
||||
test_commit -C server foo &&
|
||||
|
||||
# Fetch from the server
|
||||
git init client &&
|
||||
test_config -C client protocol.version 2 &&
|
||||
test_commit -C client bar &&
|
||||
GIT_TRACE_PACKET="$(pwd)/trace" git -C client fetch "file://$(pwd)/server" &&
|
||||
grep "version 2" trace
|
||||
'
|
||||
|
||||
. "$TEST_DIRECTORY"/lib-httpd.sh
|
||||
start_httpd
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user