When pushing, send-pack uses pack-objects to write the pack data to the receive-pack process running on the remote end. The scenarios where pack-objects dies unexpectedly, can be roughly divided based on whether the reason for the failure is _local_ (i.e. something in pack-objects caused it to fail of its own accord), or _remote_ (i.e. something in the remote receive-pack process caused it to fail, leaving the local pack-objects process with a broken pipe) If the reason for the failure is local, we expect pack-objects to report an appropriate error message to the user. However, if the reason for the failure is remote, pack-objects will merely abort because of the broken pipe, and the user is left with no clue as to the reason why the remote receive-pack process died. In certain cases, though, the receive-pack process on the other end may have produced an error message immediately before exiting. This error message may be currently waiting to be read by the local send-pack process. Therefore, we should try to read from the remote end, even when pack-objects dies unexepectedly. We accomplish this by _always_ calling receive_status() after pack_objects(). If the remote end managed to produce a well-formed status report before exiting, then receive_status() simply presents that to the user. Even if the data from the remote end cannot be understood by receive_status(), it will print that data as part of its error message. In any case, we give the user as much information about the failure as possible. Signed-off-by: Johan Herland <johan@xxxxxxxxxxx> --- builtin/send-pack.c | 13 +++---------- 1 files changed, 3 insertions(+), 10 deletions(-) diff --git a/builtin/send-pack.c b/builtin/send-pack.c index c1f6ddd..5ba5262 100644 --- a/builtin/send-pack.c +++ b/builtin/send-pack.c @@ -251,7 +251,7 @@ int send_pack(struct send_pack_args *args, int status_report = 0; int use_sideband = 0; unsigned cmds_sent = 0; - int ret; + int ret = 0; struct async demux; /* Does the other end support the reporting? */ @@ -339,25 +339,18 @@ int send_pack(struct send_pack_args *args, } if (new_refs && cmds_sent) { - if (pack_objects(out, remote_refs, extra_have, args) < 0) { - for (ref = remote_refs; ref; ref = ref->next) - ref->status = REF_STATUS_NONE; + if ((ret = pack_objects(out, remote_refs, extra_have, args))) { if (args->stateless_rpc) close(out); if (git_connection_is_socket(conn)) shutdown(fd[0], SHUT_WR); - if (use_sideband) - finish_async(&demux); - return -1; } } if (args->stateless_rpc && cmds_sent) packet_flush(out); if (status_report && cmds_sent) - ret = receive_status(in, remote_refs); - else - ret = 0; + ret |= receive_status(in, remote_refs); if (args->stateless_rpc) packet_flush(out); -- 1.7.5.rc1.3.g4d7b -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html