Reachability bitmaps are designed to speed up the "counting objects"
phase of generating a pack during a clone or fetch. They are not
optimized for Git clients sending a small topic branch via "git push".
In some cases (see [1]), using reachability bitmaps during "git push"
can cause significant performance regressions.
Add a new "push.useBitmaps" configuration variable to allow users to
tell "git push" not to use bitmaps. We already have "pack.bitmaps"
that controls the use of bitmaps, but a separate configuration variable
allows the reachability bitmaps to still be used in other areas,
such as "git upload-pack", while disabling it only for "git push".
[1]: https://lore.kernel.org/git/87zhoz8b9o.fsf@evledraar.gmail.com/
Signed-off-by: Kyle Zhao <kylezhao@tencent.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Kyle Zhao committedJun 17, 2022 at 19:06 UTC82f67ee13fb25ebed1cd722c83de49a1ac588429
4 files changed+35-1
Documentation/config/push.txt
+5
index e32801e6c9..7386fea225 100644--- a/Documentation/config/push.txt+++ b/Documentation/config/push.txt@@ -137,3 +137,8 @@ push.negotiate:: server attempt to find commits in common. If "false", Git will rely solely on the server's ref advertisement to find commits in common.++push.useBitmaps::+ If set to "false", disable use of bitmaps for "git push" even if+ `pack.useBitmaps` is "true", without preventing other git operations+ from using bitmaps. Default is true.
send-pack.c
+6
index bc0fcdbb00..662f7c2aeb 100644--- a/send-pack.c+++ b/send-pack.c@@ -84,6 +84,8 @@ static int pack_objects(int fd, struct ref *refs, struct oid_array *advertised, strvec_push(&po.args, "--progress"); if (is_repository_shallow(the_repository)) strvec_push(&po.args, "--shallow");+ if (args->disable_bitmaps)+ strvec_push(&po.args, "--no-use-bitmap-index"); po.in = -1; po.out = args->stateless_rpc ? -1 : fd; po.git_cmd = 1;@@ -487,6 +489,7 @@ int send_pack(struct send_pack_args *args, struct async demux; const char *push_cert_nonce = NULL; struct packet_reader reader;+ int use_bitmaps; if (!remote_refs) { fprintf(stderr, "No refs in common and none specified; doing nothing.\n"@@ -498,6 +501,9 @@ int send_pack(struct send_pack_args *args, if (push_negotiate) get_commons_through_negotiation(args->url, remote_refs, &commons);+ if (!git_config_get_bool("push.usebitmaps", &use_bitmaps))+ args->disable_bitmaps = !use_bitmaps;+ git_config_get_bool("transfer.advertisesid", &advertise_sid); /* Does the other end support the reporting? */
send-pack.h
+2-1
index e148fcd960..7edb80596c 100644--- a/send-pack.h+++ b/send-pack.h@@ -26,7 +26,8 @@ struct send_pack_args { /* One of the SEND_PACK_PUSH_CERT_* constants. */ push_cert:2, stateless_rpc:1,- atomic:1;+ atomic:1,+ disable_bitmaps:1; const struct string_list *push_options; };