Subject: [PATCH] send-pack.c: add config push.useBitmaps

From: "Kyle Zhao via GitGitGadget" <[email-masked]>
Date: Wed, 15 Jun 2022 11:08:40 +0000

From: Kyle Zhao <[email-masked]>

This allows you to disabled bitmaps for "git push". Default is false.

Bitmaps are designed to speed up the "counting objects" phase of
subsequent packs created for clones and fetches.
But in some cases, turning bitmaps on does horrible things for "push"
performance[1].

[1]: https://lore.kernel.org/git/[email-masked]/

Signed-off-by: Kyle Zhao <[email-masked]>
---
    send-pack.c: add config push.useBitmaps
    
    This patch add config push.useBitmaps to prevent git push using bitmap.
    
    The origin discussion is here:
    https://lore.kernel.org/git/[email-masked]/
    
    Thanks, Kyle

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1263%2Fkeyu98%2Fkz%2Fpush-usebitmps-config-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1263/keyu98/kz/push-usebitmps-config-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/1263

 Documentation/config/push.txt |  4 ++++
 send-pack.c                   |  6 ++++++
 send-pack.h                   |  3 ++-
 t/t5516-fetch-push.sh         | 11 +++++++++++
 4 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/Documentation/config/push.txt b/Documentation/config/push.txt
index e32801e6c91..d8fb0bd1414 100644
--- a/Documentation/config/push.txt
+++ b/Documentation/config/push.txt
@@ -137,3 +137,7 @@ 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 this config and `pack.useBitmaps` are both "true", git will
+	use pack bitmaps (if available) when git push. Default is false.
\ No newline at end of file
diff --git a/send-pack.c b/send-pack.c
index bc0fcdbb000..d6091571caa 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->use_bitmaps)
+		strvec_push(&po.args, "--no-use-bitmap-index");
 	po.in = -1;
 	po.out = args->stateless_rpc ? -1 : fd;
 	po.git_cmd = 1;
@@ -482,6 +484,7 @@ int send_pack(struct send_pack_args *args,
 	int use_push_options = 0;
 	int push_options_supported = 0;
 	int object_format_supported = 0;
+	int use_bitmaps = 0;
 	unsigned cmds_sent = 0;
 	int ret;
 	struct async demux;
@@ -497,6 +500,9 @@ int send_pack(struct send_pack_args *args,
 	git_config_get_bool("push.negotiate", &push_negotiate);
 	if (push_negotiate)
 		get_commons_through_negotiation(args->url, remote_refs, &commons);
+	git_config_get_bool("push.usebitmaps", &use_bitmaps);
+	if (use_bitmaps)
+		args->use_bitmaps = 1;
 
 	git_config_get_bool("transfer.advertisesid", &advertise_sid);
 
diff --git a/send-pack.h b/send-pack.h
index e148fcd9609..f7af1b0353e 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,
+		use_bitmaps:1;
 	const struct string_list *push_options;
 };
 
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index dedca106a7a..ee0b912a5e8 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -1865,4 +1865,15 @@ test_expect_success 'push warns or fails when using username:password' '
 	test_line_count = 1 warnings
 '
 
+test_expect_success 'push with config push.useBitmaps' '
+	mk_test testrepo heads/main &&
+	git checkout main &&
+	GIT_TRACE=1 git push testrepo main:test >/dev/null 2>stderr &&
+	grep "no-use-bitmap-index" stderr &&
+
+	git config push.useBitmaps true &&
+	GIT_TRACE=1 git push testrepo main:test2 >/dev/null 2>stderr &&
+	! grep "no-use-bitmap-index" stderr
+'
+
 test_done

base-commit: 8168d5e9c23ed44ae3d604f392320d66556453c9
-- 
gitgitgadget