diff options
Diffstat (limited to 'transport-helper.c')
| -rw-r--r-- | transport-helper.c | 115 |
1 files changed, 69 insertions, 46 deletions
diff --git a/transport-helper.c b/transport-helper.c index 49811ef176..bc27653cde 100644 --- a/transport-helper.c +++ b/transport-helper.c @@ -1,15 +1,15 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "transport.h" #include "quote.h" #include "run-command.h" #include "commit.h" -#include "diff.h" #include "environment.h" #include "gettext.h" #include "hex.h" #include "object-name.h" #include "repository.h" -#include "revision.h" #include "remote.h" #include "string-list.h" #include "thread-utils.h" @@ -19,11 +19,12 @@ #include "refspec.h" #include "transport-internal.h" #include "protocol.h" +#include "packfile.h" static int debug; struct helper_data { - const char *name; + char *name; struct child_process *helper; FILE *out; unsigned fetch : 1, @@ -88,11 +89,18 @@ static int recvline(struct helper_data *helper, struct strbuf *buffer) return recvline_fh(helper->out, buffer); } -static void write_constant(int fd, const char *str) +static int write_constant_gently(int fd, const char *str) { if (debug) fprintf(stderr, "Debug: Remote helper: -> %s", str); if (write_in_full(fd, str, strlen(str)) < 0) + return -1; + return 0; +} + +static void write_constant(int fd, const char *str) +{ + if (write_constant_gently(fd, str) < 0) die_errno(_("full write to remote helper failed")); } @@ -112,6 +120,7 @@ static void do_take_over(struct transport *transport) data = (struct helper_data *)transport->data; transport_take_over(transport, data->helper); fclose(data->out); + free(data->name); free(data); } @@ -141,7 +150,7 @@ static struct child_process *get_helper(struct transport *transport) if (have_git_dir()) strvec_pushf(&helper->env, "%s=%s", - GIT_DIR_ENVIRONMENT, get_git_dir()); + GIT_DIR_ENVIRONMENT, repo_get_git_dir(the_repository)); helper->trace2_child_class = helper->args.v[0]; /* "remote-<name>" */ @@ -166,13 +175,16 @@ static struct child_process *get_helper(struct transport *transport) die_errno(_("can't dup helper output fd")); data->out = xfdopen(duped, "r"); - write_constant(helper->in, "capabilities\n"); + sigchain_push(SIGPIPE, SIG_IGN); + if (write_constant_gently(helper->in, "capabilities\n") < 0) + die("remote helper '%s' aborted session", data->name); + sigchain_pop(SIGPIPE); while (1) { const char *capname, *arg; int mandatory = 0; if (recvline(data, &buf)) - exit(128); + die("remote helper '%s' aborted session", data->name); if (!*buf.buf) break; @@ -254,6 +266,7 @@ static int disconnect_helper(struct transport *transport) close(data->helper->out); fclose(data->out); res = finish_command(data->helper); + FREE_AND_NULL(data->name); FREE_AND_NULL(data->helper); } return res; @@ -386,6 +399,8 @@ static int release_helper(struct transport *transport) int res = 0; struct helper_data *data = transport->data; refspec_clear(&data->rs); + free(data->import_marks); + free(data->export_marks); res = disconnect_helper(transport); free(transport->data); return res; @@ -434,6 +449,8 @@ static int fetch_with_fetch(struct transport *transport, warning(_("%s unexpectedly said: '%s'"), data->name, buf.buf); } strbuf_release(&buf); + + reprepare_packed_git(the_repository); return 0; } @@ -550,7 +567,7 @@ static int fetch_with_import(struct transport *transport, else private = xstrdup(name); if (private) { - if (read_ref(private, &posn->old_oid) < 0) + if (refs_read_ref(get_main_ref_store(the_repository), private, &posn->old_oid) < 0) die(_("could not read ref %s"), private); free(private); } @@ -628,7 +645,8 @@ static int process_connect_service(struct transport *transport, ret = run_connect(transport, &cmdbuf); } else if (data->stateless_connect && (get_protocol_version_config() == protocol_v2) && - !strcmp("git-upload-pack", name)) { + (!strcmp("git-upload-pack", name) || + !strcmp("git-upload-archive", name))) { strbuf_addf(&cmdbuf, "stateless-connect %s\n", name); ret = run_connect(transport, &cmdbuf); if (ret) @@ -645,6 +663,7 @@ static int process_connect(struct transport *transport, struct helper_data *data = transport->data; const char *name; const char *exec; + int ret; name = for_push ? "git-receive-pack" : "git-upload-pack"; if (for_push) @@ -652,7 +671,10 @@ static int process_connect(struct transport *transport, else exec = data->transport_options.uploadpack; - return process_connect_service(transport, name, exec); + ret = process_connect_service(transport, name, exec); + if (ret) + do_take_over(transport); + return ret; } static int connect_helper(struct transport *transport, const char *name, @@ -662,14 +684,14 @@ static int connect_helper(struct transport *transport, const char *name, /* Get_helper so connect is inited. */ get_helper(transport); - if (!data->connect) - die(_("operation not supported by protocol")); if (!process_connect_service(transport, name, exec)) die(_("can't connect to subservice %s"), name); fd[0] = data->helper->out; fd[1] = data->helper->in; + + do_take_over(transport); return 0; } @@ -684,10 +706,8 @@ static int fetch_refs(struct transport *transport, get_helper(transport); - if (process_connect(transport, 0)) { - do_take_over(transport); + if (process_connect(transport, 0)) return transport->vtable->fetch_refs(transport, nr_heads, to_fetch); - } /* * If we reach here, then the server, the client, and/or the transport @@ -699,8 +719,14 @@ static int fetch_refs(struct transport *transport, return -1; } - if (!data->get_refs_list_called) - get_refs_list_using_list(transport, 0); + if (!data->get_refs_list_called) { + /* + * We do not care about the list of refs returned, but only + * that the "list" command was sent. + */ + struct ref *dummy = get_refs_list_using_list(transport, 0); + free_refs(dummy); + } count = 0; for (i = 0; i < nr_heads; i++) @@ -919,8 +945,10 @@ static int push_update_refs_status(struct helper_data *data, private = apply_refspecs(&data->rs, ref->name); if (!private) continue; - update_ref("update by helper", private, &(ref->new_oid), - NULL, 0, 0); + refs_update_ref(get_main_ref_store(the_repository), + "update by helper", private, + &(ref->new_oid), + NULL, 0, 0); free(private); } else { for (report = ref->report; report; report = report->next) { @@ -930,11 +958,12 @@ static int push_update_refs_status(struct helper_data *data, : ref->name); if (!private) continue; - update_ref("update by helper", private, - report->new_oid - ? report->new_oid - : &(ref->new_oid), - NULL, 0, 0); + refs_update_ref(get_main_ref_store(the_repository), + "update by helper", private, + report->new_oid + ? report->new_oid + : &(ref->new_oid), + NULL, 0, 0); free(private); } } @@ -1002,6 +1031,7 @@ static int push_refs_with_push(struct transport *transport, if (atomic) { reject_atomic_push(remote_refs, mirror); string_list_clear(&cas_options, 0); + strbuf_release(&buf); return 0; } else continue; @@ -1074,7 +1104,7 @@ static int push_refs_with_export(struct transport *transport, set_common_push_options(transport, data->name, flags); if (flags & TRANSPORT_PUSH_FORCE) { if (set_helper_option(transport, "force", "true") != 0) - warning(_("helper %s does not support 'force'"), data->name); + warning(_("helper %s does not support '--force'"), data->name); } helper = get_helper(transport); @@ -1101,9 +1131,11 @@ static int push_refs_with_export(struct transport *transport, int flag; /* Follow symbolic refs (mainly for HEAD). */ - name = resolve_ref_unsafe(ref->peer_ref->name, - RESOLVE_REF_READING, - &oid, &flag); + name = refs_resolve_ref_unsafe(get_main_ref_store(the_repository), + ref->peer_ref->name, + RESOLVE_REF_READING, + &oid, + &flag); if (!name || !(flag & REF_ISSYMREF)) name = ref->peer_ref->name; @@ -1144,10 +1176,8 @@ static int push_refs(struct transport *transport, { struct helper_data *data = transport->data; - if (process_connect(transport, 1)) { - do_take_over(transport); + if (process_connect(transport, 1)) return transport->vtable->push_refs(transport, remote_refs, flags); - } if (!remote_refs) { fprintf(stderr, @@ -1188,11 +1218,9 @@ static struct ref *get_refs_list(struct transport *transport, int for_push, { get_helper(transport); - if (process_connect(transport, for_push)) { - do_take_over(transport); + if (process_connect(transport, for_push)) return transport->vtable->get_refs_list(transport, for_push, transport_options); - } return get_refs_list_using_list(transport, for_push); } @@ -1210,16 +1238,13 @@ static struct ref *get_refs_list_using_list(struct transport *transport, data->get_refs_list_called = 1; helper = get_helper(transport); - if (data->object_format) { - write_str_in_full(helper->in, "option object-format\n"); - if (recvline(data, &buf) || strcmp(buf.buf, "ok")) - exit(128); - } + if (data->object_format) + set_helper_option(transport, "object-format", "true"); if (data->push && for_push) - write_str_in_full(helper->in, "list for-push\n"); + write_constant(helper->in, "list for-push\n"); else - write_str_in_full(helper->in, "list\n"); + write_constant(helper->in, "list\n"); while (1) { char *eov, *eon; @@ -1255,7 +1280,7 @@ static struct ref *get_refs_list_using_list(struct transport *transport, if (eon) { if (has_attribute(eon + 1, "unchanged")) { (*tail)->status |= REF_STATUS_UPTODATE; - if (read_ref((*tail)->name, &(*tail)->old_oid) < 0) + if (refs_read_ref(get_main_ref_store(the_repository), (*tail)->name, &(*tail)->old_oid) < 0) die(_("could not read ref %s"), (*tail)->name); } @@ -1276,10 +1301,8 @@ static int get_bundle_uri(struct transport *transport) { get_helper(transport); - if (process_connect(transport, 0)) { - do_take_over(transport); + if (process_connect(transport, 0)) return transport->vtable->get_bundle_uri(transport); - } return -1; } @@ -1297,7 +1320,7 @@ static struct transport_vtable vtable = { int transport_helper_init(struct transport *transport, const char *name) { struct helper_data *data = xcalloc(1, sizeof(*data)); - data->name = name; + data->name = xstrdup(name); transport_check_allowed(name); |
