remote-curl: send the refs to fetch-pack on stdin

Now that we can throw an arbitrary number of refs at fetch-pack using its --stdin option, we use it in the remote-curl helper to bypass the OS command line length limit. Signed-off-by: Ivan Todoroski <grnch@gmx.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Ivan Todoroski committed Apr 2, 2012 at 17:14 UTC 8150749da19a3e17623fc40320454afe89e04ca4
1 file changed +13 -5
remote-curl.c
+13 -5
@@ -290,6 +290,7 @@ static void output_refs(struct ref *refs)
290 struct rpc_state {
291 const char *service_name;
292 const char **argv;
293 + struct strbuf *stdin_preamble;
294 char *service_url;
295 char *hdr_content_type;
296 char *hdr_accept;
@@ -535,6 +536,7 @@ static int rpc_service(struct rpc_state *rpc, struct discovery *heads)
536 {
537 const char *svc = rpc->service_name;
538 struct strbuf buf = STRBUF_INIT;
539 + struct strbuf *preamble = rpc->stdin_preamble;
540 struct child_process client;
541 int err = 0;
542
@@ -545,6 +547,8 @@ static int rpc_service(struct rpc_state *rpc, struct discovery *heads)
547 client.argv = rpc->argv;
548 if (start_command(&client))
549 exit(1);
550 + if (preamble)
551 + write_or_die(client.in, preamble->buf, preamble->len);
552 if (heads)
553 write_or_die(client.in, heads->buf, heads->len);
554
@@ -626,13 +630,14 @@ static int fetch_git(struct discovery *heads,
630 int nr_heads, struct ref **to_fetch)
631 {
632 struct rpc_state rpc;
633 + struct strbuf preamble = STRBUF_INIT;
634 char *depth_arg = NULL;
630 - const char **argv;
635 int argc = 0, i, err;
636 + const char *argv[15];
637
633 - argv = xmalloc((15 + nr_heads) * sizeof(char*));
638 argv[argc++] = "fetch-pack";
639 argv[argc++] = "--stateless-rpc";
640 + argv[argc++] = "--stdin";
641 argv[argc++] = "--lock-pack";
642 if (options.followtags)
643 argv[argc++] = "--include-tag";
@@ -651,24 +656,27 @@ static int fetch_git(struct discovery *heads,
656 argv[argc++] = depth_arg;
657 }
658 argv[argc++] = url;
659 + argv[argc++] = NULL;
660 +
661 for (i = 0; i < nr_heads; i++) {
662 struct ref *ref = to_fetch[i];
663 if (!ref->name || !*ref->name)
664 die("cannot fetch by sha1 over smart http");
658 - argv[argc++] = ref->name;
665 + packet_buf_write(&preamble, "%s\n", ref->name);
666 }
660 - argv[argc++] = NULL;
667 + packet_buf_flush(&preamble);
668
669 memset(&rpc, 0, sizeof(rpc));
670 rpc.service_name = "git-upload-pack",
671 rpc.argv = argv;
672 + rpc.stdin_preamble = &preamble;
673 rpc.gzip_request = 1;
674
675 err = rpc_service(&rpc, heads);
676 if (rpc.result.len)
677 safe_write(1, rpc.result.buf, rpc.result.len);
678 strbuf_release(&rpc.result);
671 - free(argv);
679 + strbuf_release(&preamble);
680 free(depth_arg);
681 return err;
682 }