summaryrefslogtreecommitdiff
path: root/remote-curl.c
diff options
context:
space:
mode:
authorIvan Todoroski <grnch@gmx.net>2012-04-02 17:14:44 +0200
committerJunio C Hamano <gitster@pobox.com>2012-04-10 14:49:18 -0700
commit8150749da19a3e17623fc40320454afe89e04ca4 (patch)
tree1a912c45551fe0863f0dec375cfb20af716b15fa /remote-curl.c
parent078b895fefdca94995862a4cc8644198b00a89bf (diff)
downloadgit-8150749da19a3e17623fc40320454afe89e04ca4.tar.gz
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>
Diffstat (limited to 'remote-curl.c')
-rw-r--r--remote-curl.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/remote-curl.c b/remote-curl.c
index 48c20b86f3..543f2be8b0 100644
--- a/remote-curl.c
+++ b/remote-curl.c
@@ -290,6 +290,7 @@ static void output_refs(struct ref *refs)
struct rpc_state {
const char *service_name;
const char **argv;
+ struct strbuf *stdin_preamble;
char *service_url;
char *hdr_content_type;
char *hdr_accept;
@@ -535,6 +536,7 @@ static int rpc_service(struct rpc_state *rpc, struct discovery *heads)
{
const char *svc = rpc->service_name;
struct strbuf buf = STRBUF_INIT;
+ struct strbuf *preamble = rpc->stdin_preamble;
struct child_process client;
int err = 0;
@@ -545,6 +547,8 @@ static int rpc_service(struct rpc_state *rpc, struct discovery *heads)
client.argv = rpc->argv;
if (start_command(&client))
exit(1);
+ if (preamble)
+ write_or_die(client.in, preamble->buf, preamble->len);
if (heads)
write_or_die(client.in, heads->buf, heads->len);
@@ -626,13 +630,14 @@ static int fetch_git(struct discovery *heads,
int nr_heads, struct ref **to_fetch)
{
struct rpc_state rpc;
+ struct strbuf preamble = STRBUF_INIT;
char *depth_arg = NULL;
- const char **argv;
int argc = 0, i, err;
+ const char *argv[15];
- argv = xmalloc((15 + nr_heads) * sizeof(char*));
argv[argc++] = "fetch-pack";
argv[argc++] = "--stateless-rpc";
+ argv[argc++] = "--stdin";
argv[argc++] = "--lock-pack";
if (options.followtags)
argv[argc++] = "--include-tag";
@@ -651,24 +656,27 @@ static int fetch_git(struct discovery *heads,
argv[argc++] = depth_arg;
}
argv[argc++] = url;
+ argv[argc++] = NULL;
+
for (i = 0; i < nr_heads; i++) {
struct ref *ref = to_fetch[i];
if (!ref->name || !*ref->name)
die("cannot fetch by sha1 over smart http");
- argv[argc++] = ref->name;
+ packet_buf_write(&preamble, "%s\n", ref->name);
}
- argv[argc++] = NULL;
+ packet_buf_flush(&preamble);
memset(&rpc, 0, sizeof(rpc));
rpc.service_name = "git-upload-pack",
rpc.argv = argv;
+ rpc.stdin_preamble = &preamble;
rpc.gzip_request = 1;
err = rpc_service(&rpc, heads);
if (rpc.result.len)
safe_write(1, rpc.result.buf, rpc.result.len);
strbuf_release(&rpc.result);
- free(argv);
+ strbuf_release(&preamble);
free(depth_arg);
return err;
}