From: Johannes Schindelin Date: Fri, 28 Oct 2005 02:50:26 +0000 (+0200) Subject: git-fetch-pack: Support multi_ack extension X-Git-Tag: v0.99.9~7 X-Git-Url: https://git.octo.it/?p=git.git;a=commitdiff_plain;h=c4c86f07d01bc4a05126b129f644e70dd9e244d0 git-fetch-pack: Support multi_ack extension The client side support for multi_ack. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- diff --git a/connect.c b/connect.c index 5cc49f97..b8aea351 100644 --- a/connect.c +++ b/connect.c @@ -73,8 +73,11 @@ int get_ack(int fd, unsigned char *result_sha1) if (!strcmp(line, "NAK")) return 0; if (!strncmp(line, "ACK ", 3)) { - if (!get_sha1_hex(line+4, result_sha1)) + if (!get_sha1_hex(line+4, result_sha1)) { + if (strstr(line+45, "continue")) + return 2; return 1; + } } die("git-fetch_pack: expected ACK/NAK, got '%s'", line); } diff --git a/fetch-pack.c b/fetch-pack.c index b5842643..3df99110 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -19,7 +19,7 @@ static const char *exec = "git-upload-pack"; #define POPPED (1U << 4) static struct commit_list *rev_list = NULL; -static int non_common_revs = 0; +static int non_common_revs = 0, multi_ack = 0; static void rev_list_push(struct commit *commit, int mark) { @@ -157,7 +157,8 @@ static int find_common(int fd[2], unsigned char *result_sha1, continue; } - packet_write(fd[1], "want %s\n", sha1_to_hex(remote)); + packet_write(fd[1], "want %s%s\n", sha1_to_hex(remote), + multi_ack ? " multi_ack" : ""); fetching++; } packet_flush(fd[1]); @@ -171,6 +172,8 @@ static int find_common(int fd[2], unsigned char *result_sha1, if (verbose) fprintf(stderr, "have %s\n", sha1_to_hex(sha1)); if (!(31 & ++count)) { + int ack; + packet_flush(fd[1]); flushes++; @@ -180,29 +183,47 @@ static int find_common(int fd[2], unsigned char *result_sha1, */ if (count == 32) continue; - if (get_ack(fd[0], result_sha1)) { - flushes = 0; - retval = 0; - if (verbose) - fprintf(stderr, "got ack\n"); - break; - } + + do { + ack = get_ack(fd[0], result_sha1); + if (verbose && ack) + fprintf(stderr, "got ack %d %s\n", ack, + sha1_to_hex(result_sha1)); + if (ack == 1) { + flushes = 0; + multi_ack = 0; + retval = 0; + goto done; + } else if (ack == 2) { + struct commit *commit = + lookup_commit(result_sha1); + mark_common(commit, 0, 1); + retval = 0; + } + } while (ack); flushes--; } } - +done: packet_write(fd[1], "done\n"); if (verbose) fprintf(stderr, "done\n"); - if (retval != 0) + if (retval != 0) { + multi_ack = 0; flushes++; - while (flushes) { - flushes--; - if (get_ack(fd[0], result_sha1)) { + } + while (flushes || multi_ack) { + int ack = get_ack(fd[0], result_sha1); + if (ack) { if (verbose) - fprintf(stderr, "got ack\n"); - return 0; + fprintf(stderr, "got ack (%d) %s\n", ack, + sha1_to_hex(result_sha1)); + if (ack == 1) + return 0; + multi_ack = 1; + continue; } + flushes--; } return retval; } @@ -344,6 +365,11 @@ static int fetch_pack(int fd[2], int nr_match, char **match) pid_t pid; get_remote_heads(fd[0], &ref, 0, NULL, 0); + if (server_supports("multi_ack")) { + if (verbose) + fprintf(stderr, "Server supports multi_ack\n"); + multi_ack = 1; + } if (!ref) { packet_flush(fd[1]); die("no matching remote head");