diff options
Diffstat (limited to 'connect.c')
-rw-r--r-- | connect.c | 54 |
1 files changed, 25 insertions, 29 deletions
@@ -8,6 +8,7 @@ #include "connect.h" #include "url.h" #include "string-list.h" +#include "sha1-array.h" static char *server_capabilities; static const char *parse_feature_value(const char *, const char *, int *); @@ -45,13 +46,6 @@ int check_ref_type(const struct ref *ref, int flags) return check_ref(ref->name, strlen(ref->name), flags); } -static void add_extra_have(struct extra_have_objects *extra, unsigned char *sha1) -{ - ALLOC_GROW(extra->array, extra->nr + 1, extra->alloc); - hashcpy(&(extra->array[extra->nr][0]), sha1); - extra->nr++; -} - static void die_initial_contact(int got_at_least_one_head) { if (got_at_least_one_head) @@ -122,7 +116,8 @@ static void annotate_refs_with_symref_info(struct ref *ref) */ struct ref **get_remote_heads(int in, char *src_buf, size_t src_len, struct ref **list, unsigned int flags, - struct extra_have_objects *extra_have) + struct sha1_array *extra_have, + struct sha1_array *shallow_points) { struct ref **orig_list = list; int got_at_least_one_head = 0; @@ -145,9 +140,18 @@ struct ref **get_remote_heads(int in, char *src_buf, size_t src_len, if (!len) break; - if (len > 4 && !prefixcmp(buffer, "ERR ")) + if (len > 4 && starts_with(buffer, "ERR ")) die("remote error: %s", buffer + 4); + if (len == 48 && starts_with(buffer, "shallow ")) { + if (get_sha1_hex(buffer + 8, old_sha1)) + die("protocol error: expected shallow sha-1, got '%s'", buffer + 8); + if (!shallow_points) + die("repository on the other end cannot be shallow"); + sha1_array_append(shallow_points, old_sha1); + continue; + } + if (len < 42 || get_sha1_hex(buffer, old_sha1) || buffer[40] != ' ') die("protocol error: expected sha/ref, got '%s'", buffer); name = buffer + 41; @@ -160,7 +164,7 @@ struct ref **get_remote_heads(int in, char *src_buf, size_t src_len, if (extra_have && name_len == 5 && !memcmp(".have", name, 5)) { - add_extra_have(extra_have, old_sha1); + sha1_array_append(extra_have, old_sha1); continue; } @@ -530,22 +534,18 @@ static int git_use_proxy(const char *host) static struct child_process *git_proxy_connect(int fd[2], char *host) { const char *port = STR(DEFAULT_GIT_PORT); - const char **argv; struct child_process *proxy; get_host_and_port(&host, &port); - argv = xmalloc(sizeof(*argv) * 4); - argv[0] = git_proxy_command; - argv[1] = host; - argv[2] = port; - argv[3] = NULL; proxy = xcalloc(1, sizeof(*proxy)); - proxy->argv = argv; + argv_array_push(&proxy->args, git_proxy_command); + argv_array_push(&proxy->args, host); + argv_array_push(&proxy->args, port); proxy->in = -1; proxy->out = -1; if (start_command(proxy)) - die("cannot start proxy %s", argv[0]); + die("cannot start proxy %s", git_proxy_command); fd[0] = proxy->out; /* read from proxy stdout */ fd[1] = proxy->in; /* write to proxy stdin */ return proxy; @@ -659,7 +659,6 @@ struct child_process *git_connect(int fd[2], const char *url, char *hostandport, *path; struct child_process *conn = &no_fork; enum protocol protocol; - const char **arg; struct strbuf cmd = STRBUF_INIT; /* Without this we cannot rely on waitpid() to tell @@ -703,7 +702,6 @@ struct child_process *git_connect(int fd[2], const char *url, sq_quote_buf(&cmd, path); conn->in = conn->out = -1; - conn->argv = arg = xcalloc(7, sizeof(*arg)); if (protocol == PROTO_SSH) { const char *ssh = getenv("GIT_SSH"); int putty = ssh && strcasestr(ssh, "plink"); @@ -714,22 +712,21 @@ struct child_process *git_connect(int fd[2], const char *url, if (!ssh) ssh = "ssh"; - *arg++ = ssh; + argv_array_push(&conn->args, ssh); if (putty && !strcasestr(ssh, "tortoiseplink")) - *arg++ = "-batch"; + argv_array_push(&conn->args, "-batch"); if (port) { /* P is for PuTTY, p is for OpenSSH */ - *arg++ = putty ? "-P" : "-p"; - *arg++ = port; + argv_array_push(&conn->args, putty ? "-P" : "-p"); + argv_array_push(&conn->args, port); } - *arg++ = ssh_host; - } else { + argv_array_push(&conn->args, ssh_host); + } else { /* remove repo-local variables from the environment */ conn->env = local_repo_env; conn->use_shell = 1; } - *arg++ = cmd.buf; - *arg = NULL; + argv_array_push(&conn->args, cmd.buf); if (start_command(conn)) die("unable to fork"); @@ -755,7 +752,6 @@ int finish_connect(struct child_process *conn) return 0; code = finish_command(conn); - free(conn->argv); free(conn); return code; } |