]> git.ipfire.org Git - thirdparty/git.git/commitdiff
send-pack.c: add config push.useBitmaps
authorKyle Zhao <kylezhao@tencent.com>
Fri, 17 Jun 2022 19:06:19 +0000 (19:06 +0000)
committerJunio C Hamano <gitster@pobox.com>
Fri, 17 Jun 2022 21:31:01 +0000 (14:31 -0700)
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>
Documentation/config/push.txt
send-pack.c
send-pack.h
t/t5516-fetch-push.sh

index e32801e6c91d8145106514021ae200642b7c8366..7386fea225ae4d3215839eb42df28e414ccdf38b 100644 (file)
@@ -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.
index bc0fcdbb000769935e9f080164d8e02e81dbb8b3..662f7c2aeb9be883870b921bf71ab82c5ca431fc 100644 (file)
@@ -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? */
index e148fcd960994b1724f8d09c4ea4897b1cf069f0..7edb80596c7b0edf607ea5cd0f01315106d02b73 100644 (file)
@@ -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;
 };
 
index dedca106a7adee1c9b4888d81ced4e19349db39e..b3734dd2fe95ec5b1f8e1d7cd8ad6f72859c9ad5 100755 (executable)
@@ -1865,4 +1865,26 @@ 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 &&
+       test_unconfig push.useBitmaps &&
+       GIT_TRACE2_EVENT="$PWD/default" \
+       git push testrepo main:test &&
+       test_subcommand git pack-objects --all-progress-implied --revs --stdout \
+               --thin --delta-base-offset -q <default &&
+
+       test_config push.useBitmaps true &&
+       GIT_TRACE2_EVENT="$PWD/true" \
+       git push testrepo main:test2 &&
+       test_subcommand git pack-objects --all-progress-implied --revs --stdout \
+               --thin --delta-base-offset -q <true &&
+
+       test_config push.useBitmaps false &&
+       GIT_TRACE2_EVENT="$PWD/false" \
+       git push testrepo main:test3 &&
+       test_subcommand git pack-objects --all-progress-implied --revs --stdout \
+               --thin --delta-base-offset -q --no-use-bitmap-index <false
+'
+
 test_done