git-fetch-pack: Support multi_ack extension
The client side support for multi_ack. Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de> Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
parent
1bd8c8f00b
commit
c4c86f07d0
@ -73,9 +73,12 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
54
fetch-pack.c
54
fetch-pack.c
@ -19,7 +19,7 @@ static const char *exec = "git-upload-pack";
|
|||||||
#define POPPED (1U << 4)
|
#define POPPED (1U << 4)
|
||||||
|
|
||||||
static struct commit_list *rev_list = NULL;
|
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)
|
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;
|
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++;
|
fetching++;
|
||||||
}
|
}
|
||||||
packet_flush(fd[1]);
|
packet_flush(fd[1]);
|
||||||
@ -171,6 +172,8 @@ static int find_common(int fd[2], unsigned char *result_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++;
|
||||||
|
|
||||||
@ -180,29 +183,47 @@ 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)) {
|
|
||||||
|
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;
|
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;
|
retval = 0;
|
||||||
if (verbose)
|
|
||||||
fprintf(stderr, "got ack\n");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
} while (ack);
|
||||||
flushes--;
|
flushes--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
done:
|
||||||
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)
|
if (retval != 0) {
|
||||||
|
multi_ack = 0;
|
||||||
flushes++;
|
flushes++;
|
||||||
while (flushes) {
|
|
||||||
flushes--;
|
|
||||||
if (get_ack(fd[0], result_sha1)) {
|
|
||||||
if (verbose)
|
|
||||||
fprintf(stderr, "got ack\n");
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
while (flushes || multi_ack) {
|
||||||
|
int ack = get_ack(fd[0], result_sha1);
|
||||||
|
if (ack) {
|
||||||
|
if (verbose)
|
||||||
|
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;
|
return retval;
|
||||||
}
|
}
|
||||||
@ -344,6 +365,11 @@ static int fetch_pack(int fd[2], int nr_match, char **match)
|
|||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
|
||||||
get_remote_heads(fd[0], &ref, 0, NULL, 0);
|
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) {
|
if (!ref) {
|
||||||
packet_flush(fd[1]);
|
packet_flush(fd[1]);
|
||||||
die("no matching remote head");
|
die("no matching remote head");
|
||||||
|
Loading…
Reference in New Issue
Block a user