Merge branch 'fc/transport-helper-sync-error-fix'

Make sure the marks are not written out when the transport helper
did not finish happily, to avoid leaving a marks file that is out of
sync with the reality.

* fc/transport-helper-sync-error-fix:
  t5801 (remote-helpers): cleanup environment sets
  transport-helper: fix sync issue on crashes
  transport-helper: trivial cleanup
  transport-helper: propagate recvline() error pushing
  remote-helpers: make recvline return an error
  transport-helper: remove barely used xchgline()
This commit is contained in:
Junio C Hamano 2014-04-24 12:31:34 -07:00
commit d508e4a8e2
2 changed files with 67 additions and 37 deletions

View file

@ -212,19 +212,30 @@ test_expect_success 'push update refs failure' '
echo "update fail" >>file && echo "update fail" >>file &&
git commit -a -m "update fail" && git commit -a -m "update fail" &&
git rev-parse --verify testgit/origin/heads/update >expect && git rev-parse --verify testgit/origin/heads/update >expect &&
GIT_REMOTE_TESTGIT_PUSH_ERROR="non-fast forward" && test_expect_code 1 env GIT_REMOTE_TESTGIT_FAILURE="non-fast forward" \
export GIT_REMOTE_TESTGIT_PUSH_ERROR && git push origin update &&
test_expect_code 1 git push origin update &&
git rev-parse --verify testgit/origin/heads/update >actual && git rev-parse --verify testgit/origin/heads/update >actual &&
test_cmp expect actual test_cmp expect actual
) )
' '
clean_mark () {
cut -f 2 -d ' ' "$1" |
git cat-file --batch-check |
grep commit |
sort >$(basename "$1")
}
cmp_marks () {
test_when_finished "rm -rf git.marks testgit.marks" &&
clean_mark ".git/testgit/$1/git.marks" &&
clean_mark ".git/testgit/$1/testgit.marks" &&
test_cmp git.marks testgit.marks
}
test_expect_success 'proper failure checks for fetching' ' test_expect_success 'proper failure checks for fetching' '
(GIT_REMOTE_TESTGIT_FAILURE=1 && (cd local &&
export GIT_REMOTE_TESTGIT_FAILURE && test_must_fail env GIT_REMOTE_TESTGIT_FAILURE=1 git fetch 2>error &&
cd local &&
test_must_fail git fetch 2> error &&
cat error && cat error &&
grep -q "Error while running fast-import" error grep -q "Error while running fast-import" error
) )
@ -232,7 +243,11 @@ test_expect_success 'proper failure checks for fetching' '
test_expect_success 'proper failure checks for pushing' ' test_expect_success 'proper failure checks for pushing' '
(cd local && (cd local &&
test_must_fail env GIT_REMOTE_TESTGIT_FAILURE=1 git push --all git checkout -b crash master &&
echo crash >>file &&
git commit -a -m crash &&
test_must_fail env GIT_REMOTE_TESTGIT_FAILURE=1 git push --all &&
cmp_marks origin
) )
' '

View file

@ -58,7 +58,7 @@ static int recvline_fh(FILE *helper, struct strbuf *buffer, const char *name)
if (strbuf_getline(buffer, helper, '\n') == EOF) { if (strbuf_getline(buffer, helper, '\n') == EOF) {
if (debug) if (debug)
fprintf(stderr, "Debug: Remote helper quit.\n"); fprintf(stderr, "Debug: Remote helper quit.\n");
exit(128); return 1;
} }
if (debug) if (debug)
@ -71,12 +71,6 @@ static int recvline(struct helper_data *helper, struct strbuf *buffer)
return recvline_fh(helper->out, buffer, helper->name); return recvline_fh(helper->out, buffer, helper->name);
} }
static void xchgline(struct helper_data *helper, struct strbuf *buffer)
{
sendline(helper, buffer);
recvline(helper, buffer);
}
static void write_constant(int fd, const char *str) static void write_constant(int fd, const char *str)
{ {
if (debug) if (debug)
@ -163,7 +157,8 @@ static struct child_process *get_helper(struct transport *transport)
while (1) { while (1) {
const char *capname; const char *capname;
int mandatory = 0; int mandatory = 0;
recvline(data, &buf); if (recvline(data, &buf))
exit(128);
if (!*buf.buf) if (!*buf.buf)
break; break;
@ -200,15 +195,9 @@ static struct child_process *get_helper(struct transport *transport)
} else if (!strcmp(capname, "signed-tags")) { } else if (!strcmp(capname, "signed-tags")) {
data->signed_tags = 1; data->signed_tags = 1;
} else if (starts_with(capname, "export-marks ")) { } else if (starts_with(capname, "export-marks ")) {
struct strbuf arg = STRBUF_INIT; data->export_marks = xstrdup(capname + strlen("export-marks "));
strbuf_addstr(&arg, "--export-marks=");
strbuf_addstr(&arg, capname + strlen("export-marks "));
data->export_marks = strbuf_detach(&arg, NULL);
} else if (starts_with(capname, "import-marks")) { } else if (starts_with(capname, "import-marks")) {
struct strbuf arg = STRBUF_INIT; data->import_marks = xstrdup(capname + strlen("import-marks "));
strbuf_addstr(&arg, "--import-marks=");
strbuf_addstr(&arg, capname + strlen("import-marks "));
data->import_marks = strbuf_detach(&arg, NULL);
} else if (starts_with(capname, "no-private-update")) { } else if (starts_with(capname, "no-private-update")) {
data->no_private_update = 1; data->no_private_update = 1;
} else if (mandatory) { } else if (mandatory) {
@ -307,7 +296,9 @@ static int set_helper_option(struct transport *transport,
quote_c_style(value, &buf, NULL, 0); quote_c_style(value, &buf, NULL, 0);
strbuf_addch(&buf, '\n'); strbuf_addch(&buf, '\n');
xchgline(data, &buf); sendline(data, &buf);
if (recvline(data, &buf))
exit(128);
if (!strcmp(buf.buf, "ok")) if (!strcmp(buf.buf, "ok"))
ret = 0; ret = 0;
@ -379,7 +370,8 @@ static int fetch_with_fetch(struct transport *transport,
sendline(data, &buf); sendline(data, &buf);
while (1) { while (1) {
recvline(data, &buf); if (recvline(data, &buf))
exit(128);
if (starts_with(buf.buf, "lock ")) { if (starts_with(buf.buf, "lock ")) {
const char *name = buf.buf + 5; const char *name = buf.buf + 5;
@ -430,6 +422,8 @@ static int get_exporter(struct transport *transport,
struct helper_data *data = transport->data; struct helper_data *data = transport->data;
struct child_process *helper = get_helper(transport); struct child_process *helper = get_helper(transport);
int argc = 0, i; int argc = 0, i;
struct strbuf tmp = STRBUF_INIT;
memset(fastexport, 0, sizeof(*fastexport)); memset(fastexport, 0, sizeof(*fastexport));
/* we need to duplicate helper->in because we want to use it after /* we need to duplicate helper->in because we want to use it after
@ -440,10 +434,14 @@ static int get_exporter(struct transport *transport,
fastexport->argv[argc++] = "--use-done-feature"; fastexport->argv[argc++] = "--use-done-feature";
fastexport->argv[argc++] = data->signed_tags ? fastexport->argv[argc++] = data->signed_tags ?
"--signed-tags=verbatim" : "--signed-tags=warn-strip"; "--signed-tags=verbatim" : "--signed-tags=warn-strip";
if (data->export_marks) if (data->export_marks) {
fastexport->argv[argc++] = data->export_marks; strbuf_addf(&tmp, "--export-marks=%s.tmp", data->export_marks);
if (data->import_marks) fastexport->argv[argc++] = strbuf_detach(&tmp, NULL);
fastexport->argv[argc++] = data->import_marks; }
if (data->import_marks) {
strbuf_addf(&tmp, "--import-marks=%s", data->import_marks);
fastexport->argv[argc++] = strbuf_detach(&tmp, NULL);
}
for (i = 0; i < revlist_args->nr; i++) for (i = 0; i < revlist_args->nr; i++)
fastexport->argv[argc++] = revlist_args->items[i].string; fastexport->argv[argc++] = revlist_args->items[i].string;
@ -563,7 +561,9 @@ static int process_connect_service(struct transport *transport,
goto exit; goto exit;
sendline(data, &cmdbuf); sendline(data, &cmdbuf);
recvline_fh(input, &cmdbuf, name); if (recvline_fh(input, &cmdbuf, name))
exit(128);
if (!strcmp(cmdbuf.buf, "")) { if (!strcmp(cmdbuf.buf, "")) {
data->no_disconnect_req = 1; data->no_disconnect_req = 1;
if (debug) if (debug)
@ -739,16 +739,22 @@ static int push_update_ref_status(struct strbuf *buf,
return !(status == REF_STATUS_OK); return !(status == REF_STATUS_OK);
} }
static void push_update_refs_status(struct helper_data *data, static int push_update_refs_status(struct helper_data *data,
struct ref *remote_refs, struct ref *remote_refs,
int flags) int flags)
{ {
struct strbuf buf = STRBUF_INIT; struct strbuf buf = STRBUF_INIT;
struct ref *ref = remote_refs; struct ref *ref = remote_refs;
int ret = 0;
for (;;) { for (;;) {
char *private; char *private;
recvline(data, &buf); if (recvline(data, &buf)) {
ret = 1;
break;
}
if (!buf.len) if (!buf.len)
break; break;
@ -766,6 +772,7 @@ static void push_update_refs_status(struct helper_data *data,
free(private); free(private);
} }
strbuf_release(&buf); strbuf_release(&buf);
return ret;
} }
static int push_refs_with_push(struct transport *transport, static int push_refs_with_push(struct transport *transport,
@ -846,8 +853,7 @@ static int push_refs_with_push(struct transport *transport,
sendline(data, &buf); sendline(data, &buf);
strbuf_release(&buf); strbuf_release(&buf);
push_update_refs_status(data, remote_refs, flags); return push_update_refs_status(data, remote_refs, flags);
return 0;
} }
static int push_refs_with_export(struct transport *transport, static int push_refs_with_export(struct transport *transport,
@ -905,7 +911,15 @@ static int push_refs_with_export(struct transport *transport,
if (finish_command(&exporter)) if (finish_command(&exporter))
die("Error while running fast-export"); die("Error while running fast-export");
push_update_refs_status(data, remote_refs, flags); if (push_update_refs_status(data, remote_refs, flags))
return 1;
if (data->export_marks) {
strbuf_addf(&buf, "%s.tmp", data->export_marks);
rename(buf.buf, data->export_marks);
strbuf_release(&buf);
}
return 0; return 0;
} }
@ -974,7 +988,8 @@ static struct ref *get_refs_list(struct transport *transport, int for_push)
while (1) { while (1) {
char *eov, *eon; char *eov, *eon;
recvline(data, &buf); if (recvline(data, &buf))
exit(128);
if (!*buf.buf) if (!*buf.buf)
break; break;