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:
parent
69779a562a
commit
40a1046249
@ -59,8 +59,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);
|
||||
}
|
||||
|
50
fetch-pack.c
50
fetch-pack.c
@ -125,7 +125,7 @@ static int find_common(int fd[2], unsigned char *result_sha1,
|
||||
struct ref *refs)
|
||||
{
|
||||
int fetching;
|
||||
int count = 0, flushes = 0, retval;
|
||||
int count = 0, flushes = 0, multi_ack = 0, retval;
|
||||
const unsigned char *sha1;
|
||||
|
||||
for_each_ref(rev_list_append_sha1);
|
||||
@ -156,20 +156,22 @@ 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 multi_ack\n", sha1_to_hex(remote));
|
||||
fetching++;
|
||||
}
|
||||
packet_flush(fd[1]);
|
||||
if (!fetching)
|
||||
return 1;
|
||||
|
||||
flushes = 1;
|
||||
flushes = 0;
|
||||
retval = -1;
|
||||
while ((sha1 = get_rev())) {
|
||||
packet_write(fd[1], "have %s\n", sha1_to_hex(sha1));
|
||||
if (verbose)
|
||||
fprintf(stderr, "have %s\n", sha1_to_hex(sha1));
|
||||
if (!(31 & ++count)) {
|
||||
int ack;
|
||||
|
||||
packet_flush(fd[1]);
|
||||
flushes++;
|
||||
|
||||
@ -179,26 +181,48 @@ 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) {
|
||||
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--;
|
||||
}
|
||||
}
|
||||
done:
|
||||
if (multi_ack) {
|
||||
packet_flush(fd[1]);
|
||||
flushes++;
|
||||
}
|
||||
packet_write(fd[1], "done\n");
|
||||
if (verbose)
|
||||
fprintf(stderr, "done\n");
|
||||
if (retval != 0)
|
||||
flushes++;
|
||||
while (flushes) {
|
||||
flushes--;
|
||||
if (get_ack(fd[0], result_sha1)) {
|
||||
if (verbose)
|
||||
fprintf(stderr, "got ack\n");
|
||||
return 0;
|
||||
fprintf(stderr, "got ack %s\n",
|
||||
sha1_to_hex(result_sha1));
|
||||
if (!multi_ack)
|
||||
return 0;
|
||||
retval = 0;
|
||||
continue;
|
||||
}
|
||||
flushes--;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user