# [PATCH 8/8] git-fetch-pack: Support multi_ack extension

3 messages from 2005-10-28 to 2005-10-28. Participants: Johannes Schindelin.
Thread: https://gitlist.dev/t/2254

## Johannes Schindelin, 2005-10-28 02:50

Subject: [PATCH 8/8] git-fetch-pack: Support multi_ack extension
Message-ID: <Pine.LNX.4.63.0510280449240.20516@wbgn013.biozentrum.uni-wuerzburg.de>
URL: https://gitlist.dev/e/Pine.LNX.4.63.0510280449240.20516%40wbgn013.biozentrum.uni-wuerzburg.de

```

The client side support for multi_ack.

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>

---

	So yes, I forgot to rewrite the "Subject: [PATCH]" of the first 
	patch of this series. Please be gentle, I am going to bed now.

 connect.c    |    5 ++++-
 fetch-pack.c |   58 ++++++++++++++++++++++++++++++++++++++++++----------------
 2 files changed, 46 insertions(+), 17 deletions(-)

applies-to: e91233a8f0446016384e8f2c8faafc9c129b95d3
b851d9a0cad95cedc6082e6de00c25d9588519e7
diff --git a/connect.c b/connect.c
index 5cc49f9..b8aea35 100644
--- a/connect.c
+++ b/connect.c
@@ -73,8 +73,11 @@ int get_ack(int fd, unsigned char *resul
 	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 b584264..3df9911 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -19,7 +19,7 @@ static const char *exec = "git-upload-pa
 #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], unsign
 			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], unsign
 		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], unsign
 			 */
 			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_
 	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");
---
0.99.8.GIT

```

## Johannes Schindelin, 2005-10-28 03:36

Subject: Re: [PATCH 8/8] git-fetch-pack: Support multi_ack extension
Message-ID: <Pine.LNX.4.63.0510280535480.1460@wbgn013.biozentrum.uni-wuerzburg.de>
URL: https://gitlist.dev/e/Pine.LNX.4.63.0510280535480.1460%40wbgn013.biozentrum.uni-wuerzburg.de
In-Reply-To: <Pine.LNX.4.63.0510280449240.20516@wbgn013.biozentrum.uni-wuerzburg.de>

```
Hi,

never mind patch 7 and 8. I succeeded in fscking up again. Will patch 
tomorrow.

Ciao,
Dscho

```

## Johannes Schindelin, 2005-10-28 03:56

Subject: [PATCH] fix multi_ack, was Re: [PATCH 8/8] git-fetch-pack: Support multi_ack extension
Message-ID: <Pine.LNX.4.63.0510280555070.5054@wbgn013.biozentrum.uni-wuerzburg.de>
URL: https://gitlist.dev/e/Pine.LNX.4.63.0510280555070.5054%40wbgn013.biozentrum.uni-wuerzburg.de
In-Reply-To: <Pine.LNX.4.63.0510280535480.1460@wbgn013.biozentrum.uni-wuerzburg.de>

```

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
---

	I was already half asleep when I realized that

		printf("%s", "\0multi_ack");

	could not work. All the more astounding, that my tests
	said that the server has multi_ack capability. But that
	was my mixing up arguments to strstr().

	Aargh.

	On Fri, 28 Oct 2005, Johannes Schindelin wrote:

	> never mind patch 7 and 8. I succeeded in fscking up again.
	> Will patch tomorrow.

	Well, I could not sleep with such silly a bug.

 connect.c     |    5 +++--
 upload-pack.c |   10 +++++++---
 2 files changed, 10 insertions(+), 5 deletions(-)

applies-to: c45879487343238adc4e926abf0e6280a3f4291c
2c3e9bb8ab663976132315c970c0feea5176fb81
diff --git a/connect.c b/connect.c
index b8aea35..c2badc7 100644
--- a/connect.c
+++ b/connect.c
@@ -8,7 +8,7 @@
 #include <arpa/inet.h>
 #include <netdb.h>
 
-static char *server_capabilities = "";
+static char *server_capabilities = NULL;
 
 /*
  * Read all the refs from the other end
@@ -58,7 +58,8 @@ struct ref **get_remote_heads(int in, st
 
 int server_supports(const char *feature)
 {
-	return strstr(feature, server_capabilities) != NULL;
+	return server_capabilities &&
+		strstr(server_capabilities, feature) != NULL;
 }
 
 int get_ack(int fd, unsigned char *result_sha1)
diff --git a/upload-pack.c b/upload-pack.c
index 686445e..c5eff21 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -212,11 +212,15 @@ static int receive_needs(void)
 
 static int send_ref(const char *refname, const unsigned char *sha1)
 {
-	static char *capabilities = "\0multi_ack";
+	static char *capabilities = "multi_ack";
 	struct object *o = parse_object(sha1);
 
-	packet_write(1, "%s %s%s\n", sha1_to_hex(sha1), refname, capabilities);
-	capabilities = "";
+	if (capabilities)
+		packet_write(1, "%s %s%c%s\n", sha1_to_hex(sha1), refname,
+			0, capabilities);
+	else
+		packet_write(1, "%s %s\n", sha1_to_hex(sha1), refname);
+	capabilities = NULL;
 	if (!(o->flags & OUR_REF)) {
 		o->flags |= OUR_REF;
 		nr_our_refs++;
---
0.99.8.GIT

```
