diff options
author | Felipe Contreras <felipe.contreras@gmail.com> | 2014-04-12 15:33:32 -0500 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2014-04-14 14:03:33 -0700 |
commit | 3994e64d77d644df0f290f8bf5210ff0cb0adde2 (patch) | |
tree | c96da81ffda04e1d72e6464589fae51cdc245c78 /transport-helper.c | |
parent | 852e54bc0f8c7a478bf1f3a13b45fdfc6604aba7 (diff) | |
download | git-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.c | 13 |
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, |