git-fetch-pack: Implement client part of the multi_ack extension

This patch concludes the series, which makes
git-fetch-pack/git-upload-pack negotiate a potentially better set of
common revs. It should make a difference when fetching from a repository
with a few branches.

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
Johannes Schindelin 2005-10-23 03:40:13 +02:00 committed by Junio C Hamano
parent 69779a562a
commit 40a1046249
2 changed files with 41 additions and 14 deletions

View File

@ -59,8 +59,11 @@ int get_ack(int fd, unsigned char *result_sha1)
if (!strcmp(line, "NAK")) if (!strcmp(line, "NAK"))
return 0; return 0;
if (!strncmp(line, "ACK ", 3)) { 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; return 1;
}
} }
die("git-fetch_pack: expected ACK/NAK, got '%s'", line); die("git-fetch_pack: expected ACK/NAK, got '%s'", line);
} }

View File

@ -125,7 +125,7 @@ static int find_common(int fd[2], unsigned char *result_sha1,
struct ref *refs) struct ref *refs)
{ {
int fetching; int fetching;
int count = 0, flushes = 0, retval; int count = 0, flushes = 0, multi_ack = 0, retval;
const unsigned char *sha1; const unsigned char *sha1;
for_each_ref(rev_list_append_sha1); for_each_ref(rev_list_append_sha1);
@ -156,20 +156,22 @@ static int find_common(int fd[2], unsigned char *result_sha1,
continue; continue;
} }
packet_write(fd[1], "want %s\n", sha1_to_hex(remote)); packet_write(fd[1], "want %s multi_ack\n", sha1_to_hex(remote));
fetching++; fetching++;
} }
packet_flush(fd[1]); packet_flush(fd[1]);
if (!fetching) if (!fetching)
return 1; return 1;
flushes = 1; flushes = 0;
retval = -1; retval = -1;
while ((sha1 = get_rev())) { while ((sha1 = get_rev())) {
packet_write(fd[1], "have %s\n", sha1_to_hex(sha1)); packet_write(fd[1], "have %s\n", sha1_to_hex(sha1));
if (verbose) if (verbose)
fprintf(stderr, "have %s\n", sha1_to_hex(sha1)); fprintf(stderr, "have %s\n", sha1_to_hex(sha1));
if (!(31 & ++count)) { if (!(31 & ++count)) {
int ack;
packet_flush(fd[1]); packet_flush(fd[1]);
flushes++; flushes++;
@ -179,26 +181,48 @@ static int find_common(int fd[2], unsigned char *result_sha1,
*/ */
if (count == 32) if (count == 32)
continue; continue;
if (get_ack(fd[0], result_sha1)) {
flushes = 0; do {
retval = 0; ack = get_ack(fd[0], result_sha1);
if (verbose) if (verbose && ack)
fprintf(stderr, "got ack\n"); fprintf(stderr, "got ack %d %s\n", ack,
break; sha1_to_hex(result_sha1));
} if (ack == 1) {
if (!multi_ack)
flushes = 0;
retval = 0;
goto done;
} else if (ack == 2) {
multi_ack = 1;
mark_common((struct commit *)
lookup_object(result_sha1));
retval = 0;
}
} while(ack);
flushes--; flushes--;
} }
} }
done:
if (multi_ack) {
packet_flush(fd[1]);
flushes++;
}
packet_write(fd[1], "done\n"); packet_write(fd[1], "done\n");
if (verbose) if (verbose)
fprintf(stderr, "done\n"); fprintf(stderr, "done\n");
if (retval != 0)
flushes++;
while (flushes) { while (flushes) {
flushes--;
if (get_ack(fd[0], result_sha1)) { if (get_ack(fd[0], result_sha1)) {
if (verbose) if (verbose)
fprintf(stderr, "got ack\n"); fprintf(stderr, "got ack %s\n",
return 0; sha1_to_hex(result_sha1));
if (!multi_ack)
return 0;
retval = 0;
continue;
} }
flushes--;
} }
return retval; return retval;
} }