aboutsummaryrefslogtreecommitdiff
path: root/remote-curl.c
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2014-08-21 08:21:20 -0400
committerJunio C Hamano <gitster@pobox.com>2014-08-26 12:58:02 -0700
commit26be19ba8d8d2e7e3e288b395e7156d5b7af5140 (patch)
treef025f721c298e2770de4419200a85758671b153b /remote-curl.c
parent4109c28e055dba27d73cefb956bea5e611f66ec0 (diff)
downloadgit-26be19ba8d8d2e7e3e288b395e7156d5b7af5140.tar.gz
git-26be19ba8d8d2e7e3e288b395e7156d5b7af5140.tar.xz
send-pack: take refspecs over stdin
Pushing a large number of refs works over most transports, because we implement send-pack as an internal function. However, it can sometimes fail when pushing over http, because we have to spawn "git send-pack --stateless-rpc" to do the heavy lifting, and we pass each refspec on the command line. This can cause us to overflow the OS limits on the size of the command line for a large push. We can solve this by giving send-pack a --stdin option and using it from remote-curl. We already dealt with this on the fetch-pack side in 078b895 (fetch-pack: new --stdin option to read refs from stdin, 2012-04-02). The stdin option (and in particular, its use of packet-lines for stateless-rpc input) is modeled after that solution. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'remote-curl.c')
-rw-r--r--remote-curl.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/remote-curl.c b/remote-curl.c
index 0fcf2ce5f..558b9fecd 100644
--- a/remote-curl.c
+++ b/remote-curl.c
@@ -863,6 +863,7 @@ static int push_git(struct discovery *heads, int nr_spec, char **specs)
int i, err;
struct argv_array args;
struct string_list_item *cas_option;
+ struct strbuf preamble = STRBUF_INIT;
argv_array_init(&args);
argv_array_pushl(&args, "send-pack", "--stateless-rpc", "--helper-status",
@@ -880,17 +881,22 @@ static int push_git(struct discovery *heads, int nr_spec, char **specs)
for_each_string_list_item(cas_option, &cas_options)
argv_array_push(&args, cas_option->string);
argv_array_push(&args, url.buf);
+
+ argv_array_push(&args, "--stdin");
for (i = 0; i < nr_spec; i++)
- argv_array_push(&args, specs[i]);
+ packet_buf_write(&preamble, "%s\n", specs[i]);
+ packet_buf_flush(&preamble);
memset(&rpc, 0, sizeof(rpc));
rpc.service_name = "git-receive-pack",
rpc.argv = args.argv;
+ rpc.stdin_preamble = &preamble;
err = rpc_service(&rpc, heads);
if (rpc.result.len)
write_or_die(1, rpc.result.buf, rpc.result.len);
strbuf_release(&rpc.result);
+ strbuf_release(&preamble);
argv_array_clear(&args);
return err;
}