[PATCH] fetch/upload: Fix corner case with few revs
From: Johannes Schindelin <hidden>
Date: 2016-06-15 22:42:09
Subsystem:
the rest · Maintainer:
Linus Torvalds
When git-fetch-pack did not have enough revs to send, it did not realize that the server actually speaks multi_ack. The server would now continue sending ack´s, but the client would try to unpack objects. Oops. Signed-off-by: Johannes Schindelin <redacted> --- I have a sizable collection of brown paper bags by now. fetch-pack.c | 13 +++++++++---- upload-pack.c | 15 +++++++++++---- 2 files changed, 20 insertions(+), 8 deletions(-) applies-to: f4786932e8753bdd07e44829a97a47749b329ee8 9a0ea94256236f1d038b16eb834fdfa5987f308c
diff --git a/fetch-pack.c b/fetch-pack.c
index 7015dc5..b02a24a 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c@@ -224,12 +224,17 @@ done: if (retval != 0) flushes++; while (flushes) { - if (get_ack(fd[0], result_sha1)) { + int ack = get_ack(fd[0], result_sha1); + if (ack) { if (verbose) - fprintf(stderr, "got ack %s\n", + fprintf(stderr, "got ack (%d) %s\n", ack, sha1_to_hex(result_sha1)); - if (!multi_ack) - return 0; + if (!multi_ack) { + if (ack == 2) + multi_ack = 1; + else + return 0; + } retval = 0; continue; }
diff --git a/upload-pack.c b/upload-pack.c
index 25a343e..1dbde5f 100644
--- a/upload-pack.c
+++ b/upload-pack.c@@ -116,7 +116,7 @@ static int get_common_commits(void) { static char line[1000]; unsigned char sha1[20]; - int len; + int len, last_sent_was_nak = 0; track_object_refs = 0; save_commit_buffer = 0;
@@ -126,23 +126,30 @@ static int get_common_commits(void) reset_timeout(); if (!len) { - if (multi_ack || nr_has == 0) + if (multi_ack || nr_has == 0) { packet_write(1, "NAK\n"); + last_sent_was_nak = 1; + } continue; } len = strip(line, len); if (!strncmp(line, "have ", 5)) { if (got_sha1(line+5, sha1) && - (multi_ack || nr_has == 1)) + (multi_ack || nr_has == 1)) { packet_write(1, "ACK %s%s\n", sha1_to_hex(sha1), multi_ack && nr_has < MAX_HAS ? " continue" : ""); + last_sent_was_nak = 0; + } continue; } if (!strcmp(line, "done")) { - if (nr_has > 0) + if (nr_has > 0) { + if (multi_ack && !last_sent_was_nak) + packet_write(1, "NAK\n"); return 0; + } packet_write(1, "NAK\n"); return -1; }
--- 0.99.8.GIT