From: Junio C Hamano Date: Tue, 12 Feb 2008 00:47:07 +0000 (-0800) Subject: Merge branch 'db/no-separate-ls-remote-connection' (early part) X-Git-Tag: v1.5.5-rc0~228 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/40aab8119f38c622f58d8e612e7a632eb1f3ded2?hp=-c Merge branch 'db/no-separate-ls-remote-connection' (early part) * 'db/no-separate-ls-remote-connection' (early part): Fix "git clone" for git:// protocol Reduce the number of connects when fetching --- 40aab8119f38c622f58d8e612e7a632eb1f3ded2 diff --combined connect.c index 71597d4920,700cebad90..5ac3572784 --- a/connect.c +++ b/connect.c @@@ -370,8 -370,6 +370,8 @@@ static int git_proxy_command_options(co if (git_proxy_command) return 0; + if (!value) + return config_error_nonbool(var); /* [core] * ;# matches www.kernel.org as well * gitproxy = netcatter-1 for kernel.org @@@ -474,14 -472,18 +474,18 @@@ char *get_port(char *host return NULL; } + static struct child_process no_fork; + /* - * This returns NULL if the transport protocol does not need fork(2), or a - * struct child_process object if it does. Once done, finish the connection - * with finish_connect() with the value returned from this function - * (it is safe to call finish_connect() with NULL to support the former - * case). + * This returns a dummy child_process if the transport protocol does not + * need fork(2), or a struct child_process object if it does. Once done, + * finish the connection with finish_connect() with the value returned from + * this function (it is safe to call finish_connect() with NULL to support + * the former case). * - * If it returns, the connect is successful; it just dies on errors. + * If it returns, the connect is successful; it just dies on errors (this + * will hopefully be changed in a libification effort, to return NULL when + * the connection failed). */ struct child_process *git_connect(int fd[2], const char *url_orig, const char *prog, int flags) @@@ -579,7 -581,7 +583,7 @@@ free(url); if (free_path) free(path); - return NULL; + return &no_fork; } conn = xcalloc(1, sizeof(*conn)); @@@ -637,7 -639,7 +641,7 @@@ int finish_connect(struct child_process *conn) { int code; - if (!conn) + if (!conn || conn == &no_fork) return 0; code = finish_command(conn); diff --combined transport.c index 497f853721,199e9e6a0d..397983d115 --- a/transport.c +++ b/transport.c @@@ -441,12 -441,11 +441,12 @@@ static struct ref *get_refs_via_curl(st struct ref *ref = NULL; struct ref *last_ref = NULL; + if (!transport->data) + transport->data = get_http_walker(transport->url); + refs_url = xmalloc(strlen(transport->url) + 11); sprintf(refs_url, "%s/info/refs", transport->url); - http_init(); - slot = get_active_slot(); slot->results = &results; curl_easy_setopt(slot->curl, CURLOPT_FILE, &buffer); @@@ -474,6 -473,8 +474,6 @@@ return NULL; } - http_cleanup(); - data = buffer.buf; start = NULL; mid = data; @@@ -562,6 -563,8 +562,8 @@@ struct git_transport_data unsigned thin : 1; unsigned keep : 1; int depth; + struct child_process *conn; + int fd[2]; const char *uploadpack; const char *receivepack; }; @@@ -592,20 -595,20 +594,20 @@@ static int set_git_option(struct transp return 1; } + static int connect_setup(struct transport *transport) + { + struct git_transport_data *data = transport->data; + data->conn = git_connect(data->fd, transport->url, data->uploadpack, 0); + return 0; + } + static struct ref *get_refs_via_connect(struct transport *transport) { struct git_transport_data *data = transport->data; struct ref *refs; - int fd[2]; - char *dest = xstrdup(transport->url); - struct child_process *conn = git_connect(fd, dest, data->uploadpack, 0); - get_remote_heads(fd[0], &refs, 0, NULL, 0); - packet_flush(fd[1]); - - finish_connect(conn); - - free(dest); + connect_setup(transport); + get_remote_heads(data->fd[0], &refs, 0, NULL, 0); return refs; } @@@ -616,7 -619,7 +618,7 @@@ static int fetch_refs_via_pack(struct t struct git_transport_data *data = transport->data; char **heads = xmalloc(nr_heads * sizeof(*heads)); char **origh = xmalloc(nr_heads * sizeof(*origh)); - struct ref *refs; + const struct ref *refs; char *dest = xstrdup(transport->url); struct fetch_pack_args args; int i; @@@ -631,13 -634,27 +633,27 @@@ for (i = 0; i < nr_heads; i++) origh[i] = heads[i] = xstrdup(to_fetch[i]->name); - refs = fetch_pack(&args, dest, nr_heads, heads, &transport->pack_lockfile); + + refs = transport_get_remote_refs(transport); + if (!data->conn) { + struct ref *refs_tmp; + connect_setup(transport); + get_remote_heads(data->fd[0], &refs_tmp, 0, NULL, 0); + free_refs(refs_tmp); + } + + refs = fetch_pack(&args, data->fd, data->conn, transport->remote_refs, + dest, nr_heads, heads, &transport->pack_lockfile); + close(data->fd[0]); + close(data->fd[1]); + if (finish_connect(data->conn)) + refs = NULL; + data->conn = NULL; for (i = 0; i < nr_heads; i++) free(origh[i]); free(origh); free(heads); - free_refs(refs); free(dest); return (refs ? 0 : -1); } @@@ -660,7 -677,15 +676,15 @@@ static int git_transport_push(struct tr static int disconnect_git(struct transport *transport) { - free(transport->data); + struct git_transport_data *data = transport->data; + if (data->conn) { + packet_flush(data->fd[1]); + close(data->fd[0]); + close(data->fd[1]); + finish_connect(data->conn); + } + + free(data); return 0; } @@@ -720,6 -745,7 +744,7 @@@ struct transport *transport_get(struct ret->disconnect = disconnect_git; data->thin = 1; + data->conn = NULL; data->uploadpack = "git-upload-pack"; if (remote && remote->uploadpack) data->uploadpack = remote->uploadpack;