summaryrefslogtreecommitdiff
path: root/transport-helper.c
diff options
context:
space:
mode:
authorFelipe Contreras <felipe.contreras@gmail.com>2014-04-12 15:33:32 -0500
committerJunio C Hamano <gitster@pobox.com>2014-04-14 14:03:33 -0700
commit3994e64d77d644df0f290f8bf5210ff0cb0adde2 (patch)
treec96da81ffda04e1d72e6464589fae51cdc245c78 /transport-helper.c
parent852e54bc0f8c7a478bf1f3a13b45fdfc6604aba7 (diff)
downloadgit-3994e64d77d644df0f290f8bf5210ff0cb0adde2.tar.gz
transport-helper: fix sync issue on crashes
When a remote helper crashes while pushing we should revert back to the state before the push, however, it's possible that `git fast-export` already finished its job, and therefore has exported the marks already. This creates a synchronization problem because from that moment on `git fast-{import,export}` will have marks that the remote helper is not aware of and all further commands fail (if those marks are referenced). The fix is to tell `git fast-export` to export to a temporary file, and only after the remote helper has finishes successfully, move to the final destination. Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'transport-helper.c')
-rw-r--r--transport-helper.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/transport-helper.c b/transport-helper.c
index c890db620b..b468e4f88e 100644
--- a/transport-helper.c
+++ b/transport-helper.c
@@ -435,7 +435,7 @@ static int get_exporter(struct transport *transport,
fastexport->argv[argc++] = data->signed_tags ?
"--signed-tags=verbatim" : "--signed-tags=warn-strip";
if (data->export_marks) {
- strbuf_addf(&tmp, "--export-marks=%s", data->export_marks);
+ strbuf_addf(&tmp, "--export-marks=%s.tmp", data->export_marks);
fastexport->argv[argc++] = strbuf_detach(&tmp, NULL);
}
if (data->import_marks) {
@@ -911,7 +911,16 @@ static int push_refs_with_export(struct transport *transport,
if (finish_command(&exporter))
die("Error while running fast-export");
- return 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;
}
static int push_refs(struct transport *transport,