From: Junio C Hamano Date: Thu, 6 Jun 2013 19:17:22 +0000 (-0700) Subject: Merge branch 'fc/transport-helper-no-refspec' X-Git-Tag: v1.8.4-rc0~207 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/99d9ec0?hp=-c Merge branch 'fc/transport-helper-no-refspec' With "export" remote-helper protocol, (1) a push that tries to update a remote ref whose name is different from the pushing side does not work yet, and (2) the helper may not know how to do --dry-run Detect such problematic cases and disable them for now. * fc/transport-helper-no-refspec: transport-helper: check if the dry-run is supported transport-helper: barf when user tries old:new --- 99d9ec090677c925c534001f01cbaf303a31cb82 diff --combined transport-helper.c index 2f5ac3fbee,f08eff0ab6..06c08a1786 --- a/transport-helper.c +++ b/transport-helper.c @@@ -11,7 -11,6 +11,7 @@@ #include "thread-utils.h" #include "sigchain.h" #include "argv-array.h" +#include "refs.h" static int debug; @@@ -48,7 -47,7 +48,7 @@@ static void sendline(struct helper_dat die_errno("Full write to remote helper failed"); } -static int recvline_fh(FILE *helper, struct strbuf *buffer) +static int recvline_fh(FILE *helper, struct strbuf *buffer, const char *name) { strbuf_reset(buffer); if (debug) @@@ -56,7 -55,7 +56,7 @@@ if (strbuf_getline(buffer, helper, '\n') == EOF) { if (debug) fprintf(stderr, "Debug: Remote helper quit.\n"); - exit(128); + die("Reading from helper 'git-remote-%s' failed", name); } if (debug) @@@ -66,7 -65,7 +66,7 @@@ static int recvline(struct helper_data *helper, struct strbuf *buffer) { - return recvline_fh(helper->out, buffer); + return recvline_fh(helper->out, buffer, helper->name); } static void xchgline(struct helper_data *helper, struct strbuf *buffer) @@@ -218,8 -217,6 +218,8 @@@ static struct child_process *get_helper 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."); } strbuf_release(&buf); if (debug) @@@ -476,7 -473,7 +476,7 @@@ static int fetch_with_import(struct tra * were fetching. * * (If no "refspec" capability was specified, for historical - * reasons we default to *:*.) + * reasons we default to the equivalent of *:*.) * * Store the result in to_fetch[i].old_sha1. Callers such * as "git fetch" can use the value to write feedback to the @@@ -543,7 -540,7 +543,7 @@@ static int process_connect_service(stru goto exit; sendline(data, &cmdbuf); - recvline_fh(input, &cmdbuf); + recvline_fh(input, &cmdbuf, name); if (!strcmp(cmdbuf.buf, "")) { data->no_disconnect_req = 1; if (debug) @@@ -625,7 -622,7 +625,7 @@@ static int fetch(struct transport *tran return -1; } -static void push_update_ref_status(struct strbuf *buf, +static int push_update_ref_status(struct strbuf *buf, struct ref **ref, struct ref *remote_refs) { @@@ -691,7 -688,7 +691,7 @@@ *ref = find_ref_by_name(remote_refs, refname); if (!*ref) { warning("helper reported unexpected status of %s", refname); - return; + return 1; } if ((*ref)->status != REF_STATUS_NONE) { @@@ -700,12 -697,11 +700,12 @@@ * status reported by the remote helper if the latter is 'no match'. */ if (status == REF_STATUS_NONE) - return; + return 1; } (*ref)->status = status; (*ref)->remote_status = msg; + return !(status == REF_STATUS_OK); } static void push_update_refs_status(struct helper_data *data, @@@ -714,24 -710,11 +714,24 @@@ struct strbuf buf = STRBUF_INIT; struct ref *ref = remote_refs; for (;;) { + char *private; + recvline(data, &buf); if (!buf.len) break; - push_update_ref_status(&buf, &ref, remote_refs); + if (push_update_ref_status(&buf, &ref, remote_refs)) + continue; + + if (!data->refspecs) + continue; + + /* propagate back the update to the remote namespace */ + private = apply_refspecs(data->refspecs, data->refspec_nr, ref->name); + if (!private) + continue; + update_ref("update by helper", private, ref->new_sha1, NULL, 0, 0); + free(private); } strbuf_release(&buf); } @@@ -806,9 -789,11 +806,14 @@@ static int push_refs_with_export(struc struct string_list revlist_args = STRING_LIST_INIT_NODUP; struct strbuf buf = STRBUF_INIT; + if (!data->refspecs) + die("remote-helper doesn't support push; refspec needed"); + + if (flags & TRANSPORT_PUSH_DRY_RUN) { + if (set_helper_option(transport, "dry-run", "true") != 0) + die("helper %s does not support dry-run", data->name); + } + helper = get_helper(transport); write_constant(helper->in, "export\n"); @@@ -819,9 -804,8 +824,9 @@@ char *private; unsigned char sha1[20]; - if (!data->refspecs) - continue; + if (ref->deletion) + die("remote-helpers do not support ref deletion"); + private = apply_refspecs(data->refspecs, data->refspec_nr, ref->name); if (private && !get_sha1(private, sha1)) { strbuf_addf(&buf, "^%s", private); @@@ -830,8 -814,15 +835,14 @@@ } free(private); - if (ref->peer_ref) - if (ref->deletion) { ++ if (ref->deletion) + die("remote-helpers do not support ref deletion"); - } + + if (ref->peer_ref) { + if (strcmp(ref->peer_ref->name, ref->name)) + die("remote-helpers do not support old:new syntax"); string_list_append(&revlist_args, ref->peer_ref->name); + } } if (get_exporter(transport, &exporter, &revlist_args))