From 5cf7a17dfbe60ea3cfb32ace7264edc3ad97611b Mon Sep 17 00:00:00 2001 From: Jeff King Date: Wed, 27 Nov 2019 07:32:11 -0500 Subject: send-pack: use OBJECT_INFO_QUICK to check negative objects When pushing, we feed pack-objects a list of both positive and negative objects. The positive objects are what we want to send, and the negative objects are what the other side told us they have, which we can use to limit the size of the push. Before passing along a negative object, send_pack() will make sure we actually have it (since we only know about it because the remote mentioned it, not because it's one of our refs). So it's expected that some of these objects will be missing on the local side. But looking for a missing object is more expensive than one that we have: it triggers reprepare_packed_git() to handle a racy repack, plus it has to explore every alternate's loose object tree (which can be slow if you have a lot of them, or have a high-latency filesystem). This isn't usually a big problem, since repositories you're pushing to don't generally have a large number of refs that are unrelated to what the client has. But there's no reason such a setup is wrong, and it currently performs poorly. We can fix this by using OBJECT_INFO_QUICK, which tells the lookup code that we expect objects to be missing. Notably, it will not re-scan the packs, and it will use the loose cache from 61c7711cfe (sha1-file: use loose object cache for quick existence check, 2018-11-12). The downside is that in the rare case that we race with a local repack, we might fail to feed some objects to pack-objects, making the resulting push larger. But we'd never produce an invalid or incorrect push, just a less optimal one. That seems like a reasonable tradeoff, and we already do similar things on the fetch side (e.g., when marking COMPLETE commits). Signed-off-by: Jeff King Signed-off-by: Junio C Hamano diff --git a/send-pack.c b/send-pack.c index 34c77cb..16d6584 100644 --- a/send-pack.c +++ b/send-pack.c @@ -41,7 +41,9 @@ int option_parse_push_signed(const struct option *opt, static void feed_object(const struct object_id *oid, FILE *fh, int negative) { if (negative && - !has_object_file_with_flags(oid, OBJECT_INFO_SKIP_FETCH_OBJECT)) + !has_object_file_with_flags(oid, + OBJECT_INFO_SKIP_FETCH_OBJECT | + OBJECT_INFO_QUICK)) return; if (negative) -- cgit v0.10.2-6-g49f6