Commits

Anonymous committed c4c86f0

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>

  • Participants
  • Parent commits 1bd8c8f

Comments (0)

Files changed (2)

 	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);
 }

File fetch-pack.c

 #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)
 {
 			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]);
 		if (verbose)
 			fprintf(stderr, "have %s\n", sha1_to_hex(sha1));
 		if (!(31 & ++count)) {
+			int ack;
+
 			packet_flush(fd[1]);
 			flushes++;
 
 			 */
 			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;
 }
 	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");