diff options
Diffstat (limited to 'transport-helper.c')
-rw-r--r-- | transport-helper.c | 214 |
1 files changed, 113 insertions, 101 deletions
diff --git a/transport-helper.c b/transport-helper.c index 3f380d87d9..143ca008c8 100644 --- a/transport-helper.c +++ b/transport-helper.c @@ -11,7 +11,9 @@ #include "sigchain.h" #include "argv-array.h" #include "refs.h" +#include "refspec.h" #include "transport-internal.h" +#include "protocol.h" static int debug; @@ -26,6 +28,7 @@ struct helper_data { option : 1, push : 1, connect : 1, + stateless_connect : 1, signed_tags : 1, check_connectivity : 1, no_disconnect_req : 1, @@ -33,8 +36,7 @@ struct helper_data { char *export_marks; char *import_marks; /* These go from remote name (as in "list") to private name */ - struct refspec *refspecs; - int refspec_nr; + struct refspec rs; /* Transport options for fetch-pack/send-pack (should one of * those be invoked). */ @@ -46,10 +48,10 @@ static void sendline(struct helper_data *helper, struct strbuf *buffer) if (debug) fprintf(stderr, "Debug: Remote helper: -> %s", buffer->buf); if (write_in_full(helper->helper->in, buffer->buf, buffer->len) < 0) - die_errno("Full write to remote helper failed"); + die_errno(_("full write to remote helper failed")); } -static int recvline_fh(FILE *helper, struct strbuf *buffer, const char *name) +static int recvline_fh(FILE *helper, struct strbuf *buffer) { strbuf_reset(buffer); if (debug) @@ -67,7 +69,7 @@ static int recvline_fh(FILE *helper, struct strbuf *buffer, const char *name) static int recvline(struct helper_data *helper, struct strbuf *buffer) { - return recvline_fh(helper->out, buffer, helper->name); + return recvline_fh(helper->out, buffer); } static void write_constant(int fd, const char *str) @@ -75,7 +77,7 @@ static void write_constant(int fd, const char *str) if (debug) fprintf(stderr, "Debug: Remote helper: -> %s", str); if (write_in_full(fd, str, strlen(str)) < 0) - die_errno("Full write to remote helper failed"); + die_errno(_("full write to remote helper failed")); } static const char *remove_ext_force(const char *url) @@ -104,9 +106,6 @@ static struct child_process *get_helper(struct transport *transport) struct helper_data *data = transport->data; struct strbuf buf = STRBUF_INIT; struct child_process *helper; - const char **refspecs = NULL; - int refspec_nr = 0; - int refspec_alloc = 0; int duped; int code; @@ -130,12 +129,13 @@ static struct child_process *get_helper(struct transport *transport) code = start_command(helper); if (code < 0 && errno == ENOENT) - die("Unable to find remote helper for '%s'", data->name); + die(_("unable to find remote helper for '%s'"), data->name); else if (code != 0) exit(code); data->helper = helper; data->no_disconnect_req = 0; + refspec_init(&data->rs, REFSPEC_FETCH); /* * Open the output as FILE* so strbuf_getline_*() family of @@ -145,7 +145,7 @@ static struct child_process *get_helper(struct transport *transport) */ duped = dup(helper->out); if (duped < 0) - die_errno("Can't dup helper output fd"); + die_errno(_("can't dup helper output fd")); data->out = xfdopen(duped, "r"); write_constant(helper->in, "capabilities\n"); @@ -181,13 +181,12 @@ static struct child_process *get_helper(struct transport *transport) data->export = 1; else if (!strcmp(capname, "check-connectivity")) data->check_connectivity = 1; - else if (!data->refspecs && skip_prefix(capname, "refspec ", &arg)) { - ALLOC_GROW(refspecs, - refspec_nr + 1, - refspec_alloc); - refspecs[refspec_nr++] = xstrdup(arg); + else if (skip_prefix(capname, "refspec ", &arg)) { + refspec_append(&data->rs, arg); } else if (!strcmp(capname, "connect")) { data->connect = 1; + } else if (!strcmp(capname, "stateless-connect")) { + data->stateless_connect = 1; } else if (!strcmp(capname, "signed-tags")) { data->signed_tags = 1; } else if (skip_prefix(capname, "export-marks ", &arg)) { @@ -197,20 +196,13 @@ static struct child_process *get_helper(struct transport *transport) } else if (starts_with(capname, "no-private-update")) { data->no_private_update = 1; } else if (mandatory) { - die("Unknown mandatory capability %s. This remote " - "helper probably needs newer version of Git.", + die(_("unknown mandatory capability %s; this remote " + "helper probably needs newer version of Git"), capname); } } - if (refspecs) { - int i; - data->refspec_nr = refspec_nr; - data->refspecs = parse_fetch_refspec(refspec_nr, refspecs); - for (i = 0; i < refspec_nr; i++) - free((char *)refspecs[i]); - free(refspecs); - } else if (data->import || data->bidi_import || data->export) { - warning("This remote helper should implement refspec capability."); + if (!data->rs.nr && (data->import || data->bidi_import || data->export)) { + warning(_("this remote helper should implement refspec capability")); } strbuf_release(&buf); if (debug) @@ -277,7 +269,7 @@ static int strbuf_set_helper_option(struct helper_data *data, else if (!strcmp(buf->buf, "unsupported")) ret = 1; else { - warning("%s unexpectedly said: '%s'", data->name, buf->buf); + warning(_("%s unexpectedly said: '%s'"), data->name, buf->buf); ret = 1; } return ret; @@ -373,8 +365,7 @@ static int release_helper(struct transport *transport) { int res = 0; struct helper_data *data = transport->data; - free_refspec(data->refspec_nr, data->refspecs); - data->refspecs = NULL; + refspec_clear(&data->rs); res = disconnect_helper(transport); free(transport->data); return res; @@ -407,7 +398,7 @@ static int fetch_with_fetch(struct transport *transport, if (starts_with(buf.buf, "lock ")) { const char *name = buf.buf + 5; if (transport->pack_lockfile) - warning("%s also locked %s", data->name, name); + warning(_("%s also locked %s"), data->name, name); else transport->pack_lockfile = xstrdup(name); } @@ -418,7 +409,7 @@ static int fetch_with_fetch(struct transport *transport, else if (!buf.len) break; else - warning("%s unexpectedly said: '%s'", data->name, buf.buf); + warning(_("%s unexpectedly said: '%s'"), data->name, buf.buf); } strbuf_release(&buf); return 0; @@ -485,7 +476,7 @@ static int fetch_with_import(struct transport *transport, get_helper(transport); if (get_importer(transport, &fastimport)) - die("Couldn't run fast-import"); + die(_("couldn't run fast-import")); for (i = 0; i < nr_heads; i++) { posn = to_fetch[i]; @@ -508,7 +499,7 @@ static int fetch_with_import(struct transport *transport, */ if (finish_command(&fastimport)) - die("Error while running fast-import"); + die(_("error while running fast-import")); /* * The fast-import stream of a remote helper that advertises @@ -531,13 +522,13 @@ static int fetch_with_import(struct transport *transport, if (posn->status & REF_STATUS_UPTODATE) continue; name = posn->symref ? posn->symref : posn->name; - if (data->refspecs) - private = apply_refspecs(data->refspecs, data->refspec_nr, name); + if (data->rs.nr) + private = apply_refspecs(&data->rs, name); else private = xstrdup(name); if (private) { if (read_ref(private, &posn->old_oid) < 0) - die("Could not read ref %s", private); + die(_("could not read ref %s"), private); free(private); } } @@ -545,14 +536,13 @@ static int fetch_with_import(struct transport *transport, return 0; } -static int process_connect_service(struct transport *transport, - const char *name, const char *exec) +static int run_connect(struct transport *transport, struct strbuf *cmdbuf) { struct helper_data *data = transport->data; - struct strbuf cmdbuf = STRBUF_INIT; - struct child_process *helper; - int r, duped, ret = 0; + int ret = 0; + int duped; FILE *input; + struct child_process *helper; helper = get_helper(transport); @@ -564,51 +554,68 @@ static int process_connect_service(struct transport *transport, */ duped = dup(helper->out); if (duped < 0) - die_errno("Can't dup helper output fd"); + die_errno(_("can't dup helper output fd")); input = xfdopen(duped, "r"); setvbuf(input, NULL, _IONBF, 0); - /* - * Handle --upload-pack and friends. This is fire and forget... - * just warn if it fails. - */ - if (strcmp(name, exec)) { - r = set_helper_option(transport, "servpath", exec); - if (r > 0) - warning("Setting remote service path not supported by protocol."); - else if (r < 0) - warning("Invalid remote service path."); - } - - if (data->connect) - strbuf_addf(&cmdbuf, "connect %s\n", name); - else - goto exit; - - sendline(data, &cmdbuf); - if (recvline_fh(input, &cmdbuf, name)) + sendline(data, cmdbuf); + if (recvline_fh(input, cmdbuf)) exit(128); - if (!strcmp(cmdbuf.buf, "")) { + if (!strcmp(cmdbuf->buf, "")) { data->no_disconnect_req = 1; if (debug) fprintf(stderr, "Debug: Smart transport connection " "ready.\n"); ret = 1; - } else if (!strcmp(cmdbuf.buf, "fallback")) { + } else if (!strcmp(cmdbuf->buf, "fallback")) { if (debug) fprintf(stderr, "Debug: Falling back to dumb " "transport.\n"); - } else - die("Unknown response to connect: %s", - cmdbuf.buf); + } else { + die(_(_("unknown response to connect: %s")), + cmdbuf->buf); + } -exit: - strbuf_release(&cmdbuf); fclose(input); return ret; } +static int process_connect_service(struct transport *transport, + const char *name, const char *exec) +{ + struct helper_data *data = transport->data; + struct strbuf cmdbuf = STRBUF_INIT; + int ret = 0; + + /* + * Handle --upload-pack and friends. This is fire and forget... + * just warn if it fails. + */ + if (strcmp(name, exec)) { + int r = set_helper_option(transport, "servpath", exec); + if (r > 0) + warning(_("setting remote service path not supported by protocol")); + else if (r < 0) + warning(_("invalid remote service path")); + } + + if (data->connect) { + strbuf_addf(&cmdbuf, "connect %s\n", name); + ret = run_connect(transport, &cmdbuf); + } else if (data->stateless_connect && + (get_protocol_version_config() == protocol_v2) && + !strcmp("git-upload-pack", name)) { + strbuf_addf(&cmdbuf, "stateless-connect %s\n", name); + ret = run_connect(transport, &cmdbuf); + if (ret) + transport->stateless_rpc = 1; + } + + strbuf_release(&cmdbuf); + return ret; +} + static int process_connect(struct transport *transport, int for_push) { @@ -633,10 +640,10 @@ 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."); + die(_("operation not supported by protocol")); if (!process_connect_service(transport, name, exec)) - die("Can't connect to subservice %s.", name); + die(_("can't connect to subservice %s"), name); fd[0] = data->helper->out; fd[1] = data->helper->in; @@ -677,6 +684,9 @@ static int fetch(struct transport *transport, transport, "filter", data->transport_options.filter_options.filter_spec); + if (data->transport_options.negotiation_tips) + warning("Ignoring --negotiation-tip because the protocol does not support it."); + if (data->fetch) return fetch_with_fetch(transport, nr_heads, to_fetch); @@ -700,7 +710,7 @@ static int push_update_ref_status(struct strbuf *buf, status = REF_STATUS_REMOTE_REJECT; refname = buf->buf + 6; } else - die("expected ok/error, helper said '%s'", buf->buf); + die(_("expected ok/error, helper said '%s'"), buf->buf); msg = strchr(refname, ' '); if (msg) { @@ -753,7 +763,7 @@ static int push_update_ref_status(struct strbuf *buf, if (!*ref) *ref = find_ref_by_name(remote_refs, refname); if (!*ref) { - warning("helper reported unexpected status of %s", refname); + warning(_("helper reported unexpected status of %s"), refname); return 1; } @@ -794,11 +804,11 @@ static int push_update_refs_status(struct helper_data *data, if (push_update_ref_status(&buf, &ref, remote_refs)) continue; - if (flags & TRANSPORT_PUSH_DRY_RUN || !data->refspecs || data->no_private_update) + if (flags & TRANSPORT_PUSH_DRY_RUN || !data->rs.nr || data->no_private_update) continue; /* propagate back the update to the remote namespace */ - private = apply_refspecs(data->refspecs, data->refspec_nr, ref->name); + private = apply_refspecs(&data->rs, ref->name); if (!private) continue; update_ref("update by helper", private, &ref->new_oid, NULL, @@ -814,20 +824,20 @@ static void set_common_push_options(struct transport *transport, { if (flags & TRANSPORT_PUSH_DRY_RUN) { if (set_helper_option(transport, "dry-run", "true") != 0) - die("helper %s does not support dry-run", name); + die(_("helper %s does not support dry-run"), name); } else if (flags & TRANSPORT_PUSH_CERT_ALWAYS) { if (set_helper_option(transport, TRANS_OPT_PUSH_CERT, "true") != 0) - die("helper %s does not support --signed", name); + die(_("helper %s does not support --signed"), name); } else if (flags & TRANSPORT_PUSH_CERT_IF_ASKED) { if (set_helper_option(transport, TRANS_OPT_PUSH_CERT, "if-asked") != 0) - die("helper %s does not support --signed=if-asked", name); + die(_("helper %s does not support --signed=if-asked"), name); } if (flags & TRANSPORT_PUSH_OPTIONS) { struct string_list_item *item; for_each_string_list_item(item, transport->push_options) if (set_helper_option(transport, "push-option", item->string) != 0) - die("helper %s does not support 'push-option'", name); + die(_("helper %s does not support 'push-option'"), name); } } @@ -918,13 +928,13 @@ static int push_refs_with_export(struct transport *transport, struct string_list revlist_args = STRING_LIST_INIT_DUP; struct strbuf buf = STRBUF_INIT; - if (!data->refspecs) - die("remote-helper doesn't support push; refspec needed"); + if (!data->rs.nr) + die(_("remote-helper doesn't support push; refspec needed")); 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); @@ -935,7 +945,7 @@ static int push_refs_with_export(struct transport *transport, char *private; struct object_id oid; - private = apply_refspecs(data->refspecs, data->refspec_nr, ref->name); + private = apply_refspecs(&data->rs, ref->name); if (private && !get_oid(private, &oid)) { strbuf_addf(&buf, "^%s", private); string_list_append_nodup(&revlist_args, @@ -971,12 +981,12 @@ static int push_refs_with_export(struct transport *transport, } if (get_exporter(transport, &exporter, &revlist_args)) - die("Couldn't run fast-export"); + die(_("couldn't run fast-export")); string_list_clear(&revlist_args, 1); if (finish_command(&exporter)) - die("Error while running fast-export"); + die(_("error while running fast-export")); if (push_update_refs_status(data, remote_refs, flags)) return 1; @@ -1000,8 +1010,9 @@ static int push_refs(struct transport *transport, } if (!remote_refs) { - fprintf(stderr, "No refs in common and none specified; doing nothing.\n" - "Perhaps you should specify a branch such as 'master'.\n"); + fprintf(stderr, + _("No refs in common and none specified; doing nothing.\n" + "Perhaps you should specify a branch such as 'master'.\n")); return 0; } @@ -1031,7 +1042,8 @@ static int has_attribute(const char *attrs, const char *attr) { } } -static struct ref *get_refs_list(struct transport *transport, int for_push) +static struct ref *get_refs_list(struct transport *transport, int for_push, + const struct argv_array *ref_prefixes) { struct helper_data *data = transport->data; struct child_process *helper; @@ -1044,7 +1056,7 @@ static struct ref *get_refs_list(struct transport *transport, int for_push) if (process_connect(transport, for_push)) { do_take_over(transport); - return transport->vtable->get_refs_list(transport, for_push); + return transport->vtable->get_refs_list(transport, for_push, ref_prefixes); } if (data->push && for_push) @@ -1062,7 +1074,7 @@ static struct ref *get_refs_list(struct transport *transport, int for_push) eov = strchr(buf.buf, ' '); if (!eov) - die("Malformed response in ref list: %s", buf.buf); + die(_("malformed response in ref list: %s"), buf.buf); eon = strchr(eov + 1, ' '); *eov = '\0'; if (eon) @@ -1076,7 +1088,7 @@ static struct ref *get_refs_list(struct transport *transport, int for_push) if (has_attribute(eon + 1, "unchanged")) { (*tail)->status |= REF_STATUS_UPTODATE; if (read_ref((*tail)->name, &(*tail)->old_oid) < 0) - die(_("Could not read ref %s"), + die(_("could not read ref %s"), (*tail)->name); } } @@ -1215,7 +1227,7 @@ static int udt_do_read(struct unidirectional_transfer *t) bytes = read(t->src, t->buf + t->bufuse, BUFFERSIZE - t->bufuse); if (bytes < 0 && errno != EWOULDBLOCK && errno != EAGAIN && errno != EINTR) { - error_errno("read(%s) failed", t->src_name); + error_errno(_("read(%s) failed"), t->src_name); return -1; } else if (bytes == 0) { transfer_debug("%s EOF (with %i bytes in buffer)", @@ -1242,7 +1254,7 @@ static int udt_do_write(struct unidirectional_transfer *t) transfer_debug("%s is writable", t->dest_name); bytes = xwrite(t->dest, t->buf, t->bufuse); if (bytes < 0 && errno != EWOULDBLOCK) { - error_errno("write(%s) failed", t->dest_name); + error_errno(_("write(%s) failed"), t->dest_name); return -1; } else if (bytes > 0) { t->bufuse -= bytes; @@ -1291,11 +1303,11 @@ static int tloop_join(pthread_t thread, const char *name) void *tret; err = pthread_join(thread, &tret); if (!tret) { - error("%s thread failed", name); + error(_("%s thread failed"), name); return 1; } if (err) { - error("%s thread failed to join: %s", name, strerror(err)); + error(_("%s thread failed to join: %s"), name, strerror(err)); return 1; } return 0; @@ -1314,11 +1326,11 @@ static int tloop_spawnwait_tasks(struct bidirectional_transfer_state *s) err = pthread_create(>p_thread, NULL, udt_copy_task_routine, &s->gtp); if (err) - die("Can't start thread for copying data: %s", strerror(err)); + die(_("can't start thread for copying data: %s"), strerror(err)); err = pthread_create(&ptg_thread, NULL, udt_copy_task_routine, &s->ptg); if (err) - die("Can't start thread for copying data: %s", strerror(err)); + die(_("can't start thread for copying data: %s"), strerror(err)); ret |= tloop_join(gtp_thread, "Git to program copy"); ret |= tloop_join(ptg_thread, "Program to git copy"); @@ -1355,11 +1367,11 @@ static int tloop_join(pid_t pid, const char *name) { int tret; if (waitpid(pid, &tret, 0) < 0) { - error_errno("%s process failed to wait", name); + error_errno(_("%s process failed to wait"), name); return 1; } if (!WIFEXITED(tret) || WEXITSTATUS(tret)) { - error("%s process failed", name); + error(_("%s process failed"), name); return 1; } return 0; @@ -1377,7 +1389,7 @@ static int tloop_spawnwait_tasks(struct bidirectional_transfer_state *s) /* Fork thread #1: git to program. */ pid1 = fork(); if (pid1 < 0) - die_errno("Can't start thread for copying data"); + die_errno(_("can't start thread for copying data")); else if (pid1 == 0) { udt_kill_transfer(&s->ptg); exit(udt_copy_task_routine(&s->gtp) ? 0 : 1); @@ -1386,7 +1398,7 @@ static int tloop_spawnwait_tasks(struct bidirectional_transfer_state *s) /* Fork thread #2: program to git. */ pid2 = fork(); if (pid2 < 0) - die_errno("Can't start thread for copying data"); + die_errno(_("can't start thread for copying data")); else if (pid2 == 0) { udt_kill_transfer(&s->gtp); exit(udt_copy_task_routine(&s->ptg) ? 0 : 1); |