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>
This commit is contained in:

committed by
Junio C Hamano

parent
4109c28e05
commit
26be19ba8d
@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user