diff options
Diffstat (limited to 'transport-helper.c')
-rw-r--r-- | transport-helper.c | 55 |
1 files changed, 48 insertions, 7 deletions
diff --git a/transport-helper.c b/transport-helper.c index db9bd18..673b7c2 100644 --- a/transport-helper.c +++ b/transport-helper.c @@ -27,7 +27,9 @@ struct helper_data { push : 1, connect : 1, signed_tags : 1, - no_disconnect_req : 1; + check_connectivity : 1, + no_disconnect_req : 1, + no_private_update : 1; char *export_marks; char *import_marks; /* These go from remote name (as in "list") to private name */ @@ -186,6 +188,8 @@ static struct child_process *get_helper(struct transport *transport) data->bidi_import = 1; else if (!strcmp(capname, "export")) data->export = 1; + else if (!strcmp(capname, "check-connectivity")) + data->check_connectivity = 1; else if (!data->refspecs && !prefixcmp(capname, "refspec ")) { ALLOC_GROW(refspecs, refspec_nr + 1, @@ -205,6 +209,8 @@ static struct child_process *get_helper(struct transport *transport) strbuf_addstr(&arg, "--import-marks="); strbuf_addstr(&arg, capname + strlen("import-marks ")); data->import_marks = strbuf_detach(&arg, NULL); + } else if (!prefixcmp(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.", @@ -263,6 +269,7 @@ static const char *unsupported_options[] = { TRANS_OPT_THIN, TRANS_OPT_KEEP }; + static const char *boolean_options[] = { TRANS_OPT_THIN, TRANS_OPT_KEEP, @@ -349,6 +356,9 @@ static int fetch_with_fetch(struct transport *transport, struct strbuf buf = STRBUF_INIT; standard_options(transport); + if (data->check_connectivity && + data->transport_options.check_self_contained_and_connected) + set_helper_option(transport, "check-connectivity", "true"); for (i = 0; i < nr_heads; i++) { const struct ref *posn = to_fetch[i]; @@ -372,6 +382,10 @@ static int fetch_with_fetch(struct transport *transport, else transport->pack_lockfile = xstrdup(name); } + else if (data->check_connectivity && + data->transport_options.check_self_contained_and_connected && + !strcmp(buf.buf, "connectivity-ok")) + data->transport_options.self_contained_and_connected = 1; else if (!buf.len) break; else @@ -683,6 +697,11 @@ static int push_update_ref_status(struct strbuf *buf, free(msg); msg = NULL; } + else if (!strcmp(msg, "stale info")) { + status = REF_STATUS_REJECT_STALE; + free(msg); + msg = NULL; + } } if (*ref) @@ -723,7 +742,7 @@ static void push_update_refs_status(struct helper_data *data, if (push_update_ref_status(&buf, &ref, remote_refs)) continue; - if (!data->refspecs) + if (!data->refspecs || data->no_private_update) continue; /* propagate back the update to the remote namespace */ @@ -737,13 +756,15 @@ static void push_update_refs_status(struct helper_data *data, } static int push_refs_with_push(struct transport *transport, - struct ref *remote_refs, int flags) + struct ref *remote_refs, int flags) { int force_all = flags & TRANSPORT_PUSH_FORCE; int mirror = flags & TRANSPORT_PUSH_MIRROR; struct helper_data *data = transport->data; struct strbuf buf = STRBUF_INIT; struct ref *ref; + struct string_list cas_options = STRING_LIST_INIT_DUP; + struct string_list_item *cas_option; get_helper(transport); if (!data->push) @@ -756,6 +777,7 @@ static int push_refs_with_push(struct transport *transport, /* Check for statuses set by set_ref_status_for_push() */ switch (ref->status) { case REF_STATUS_REJECT_NONFASTFORWARD: + case REF_STATUS_REJECT_STALE: case REF_STATUS_REJECT_ALREADY_EXISTS: case REF_STATUS_UPTODATE: continue; @@ -778,11 +800,29 @@ static int push_refs_with_push(struct transport *transport, strbuf_addch(&buf, ':'); strbuf_addstr(&buf, ref->name); strbuf_addch(&buf, '\n'); + + /* + * The "--force-with-lease" options without explicit + * values to expect have already been expanded into + * the ref->old_sha1_expect[] field; we can ignore + * transport->smart_options->cas altogether and instead + * can enumerate them from the refs. + */ + if (ref->expect_old_sha1) { + struct strbuf cas = STRBUF_INIT; + strbuf_addf(&cas, "%s:%s", + ref->name, sha1_to_hex(ref->old_sha1_expect)); + string_list_append(&cas_options, strbuf_detach(&cas, NULL)); + } } - if (buf.len == 0) + if (buf.len == 0) { + string_list_clear(&cas_options, 0); return 0; + } standard_options(transport); + for_each_string_list_item(cas_option, &cas_options) + set_helper_option(transport, "cas", cas_option->string); if (flags & TRANSPORT_PUSH_DRY_RUN) { if (set_helper_option(transport, "dry-run", "true") != 0) @@ -982,6 +1022,7 @@ int transport_helper_init(struct transport *transport, const char *name) #define PBUFFERSIZE 8192 /* Print bidirectional transfer loop debug message. */ +__attribute__((format (printf, 1, 2))) static void transfer_debug(const char *fmt, ...) { va_list args; @@ -1067,7 +1108,7 @@ static int udt_do_read(struct unidirectional_transfer *t) return -1; } else if (bytes == 0) { transfer_debug("%s EOF (with %i bytes in buffer)", - t->src_name, t->bufuse); + t->src_name, (int)t->bufuse); t->state = SSTATE_FLUSHING; } else if (bytes > 0) { t->bufuse += bytes; @@ -1131,7 +1172,7 @@ static void *udt_copy_task_routine(void *udt) #ifndef NO_PTHREADS /* - * Join thread, with apporiate errors on failure. Name is name for the + * Join thread, with appropriate errors on failure. Name is name for the * thread (for error messages). Returns 0 on success, 1 on failure. */ static int tloop_join(pthread_t thread, const char *name) @@ -1197,7 +1238,7 @@ static void udt_kill_transfer(struct unidirectional_transfer *t) } /* - * Join process, with apporiate errors on failure. Name is name for the + * Join process, with appropriate errors on failure. Name is name for the * process (for error messages). Returns 0 on success, 1 on failure. */ static int tloop_join(pid_t pid, const char *name) |