shithub: git9

Download patch

ref: 1549f34ceeb99e24edea6618ef148c78e68baa31
parent: 386de35205a7d2b4ac4ea91b0fe8ac3041f7986e
author: Ori Bernstein <ori@eigenstate.org>
date: Sun Nov 15 00:04:58 EST 2020

git/send: respect capabilities

Some systems (*cough* us) dont' know when the packfile ends,
and hang.

--- a/send.c
+++ b/send.c
@@ -7,6 +7,7 @@
 typedef struct Buf	Buf;
 typedef struct Compout	Compout;
 typedef struct Update	Update;
+typedef struct Capset	Capset;
 
 struct Buf {
 	int off;
@@ -30,6 +31,12 @@
 	Hash	ours;
 };
 
+struct Capset {
+	int	sideband;
+	int	sideband64k;
+	int	report;
+};
+
 int sendall;
 int force;
 int nbranch;
@@ -284,14 +291,44 @@
 	return nu;	
 }
 
+char *
+matchcap(char *s, char *cap, int full)
+{
+	if(strncmp(s, cap, strlen(cap)) == 0)
+		if(!full || strlen(s) == strlen(cap))
+			return s + strlen(cap);
+	return nil;
+}
+
+void
+parsecaps(char *caps, Capset *cs)
+{
+	char *p, *n;
+
+	memset(cs, 0, sizeof(Capset));
+	for(p = caps; p != nil; p = n){
+		n = strchr(p, ' ');
+		if(n != nil)
+			*n++ = 0;
+		if(matchcap(p, "report-status", 1) != nil)
+			cs->report = 1;
+		if(matchcap(p, "side-band", 1) != nil)
+			cs->sideband = 1;
+		if(matchcap(p, "side-band-64k", 1) != nil)
+			cs->sideband64k = 1;
+	}
+}
+
 int
 sendpack(Conn *c)
 {
-	int i, n, r, nupd, nsp, send;
+	int i, n, r, nupd, nsp, send, first;
 	char buf[Pktmax], *sp[3];
 	Update *upd, *u;
 	Object *a, *b, *p;
+	Capset cs;
 
+	first = 1;
 	nupd = readours(&upd);
 	while(1){
 		n = readpkt(c, buf, sizeof(buf));
@@ -299,6 +336,9 @@
 			return -1;
 		if(n == 0)
 			break;
+		if(first && n > strlen(buf))
+			parsecaps(buf + strlen(buf) + 1, &cs);
+		first = 0;
 		if(strncmp(buf, "ERR ", 4) == 0)
 			sysfatal("%s", buf + 4);
 
@@ -353,7 +393,7 @@
 		 * Github doesn't advertise any capabilities, so we can't check
 		 * for compatibility. We just need to add it blindly.
 		 */
-		if(i == 0){
+		if(i == 0 && cs.report){
 			buf[n++] = '\0';
 			n += snprint(buf + n, sizeof(buf) - n, " report-status");
 		}
@@ -370,15 +410,13 @@
 	if(!send)
 		print("nothing to send\n");
 	if(send){
-		if(chattygit)
-			fprint(2, "sending pack...\n");
+		dprint(1, "sending pack...\n");
 		if(writepackdata(c, upd, nupd) == -1)
 			return -1;
-
-		if(readphase(c) == -1)
+		if(cs.report && readphase(c) == -1)
 			return -1;
 		/* We asked for a status report, may as well use it. */
-		while((n = readpkt(c, buf, sizeof(buf))) > 0){
+		while(cs.report && (n = readpkt(c, buf, sizeof(buf))) > 0){
  			buf[n] = 0;
 			if(chattygit)
 				fprint(2, "done sending pack, status %s\n", buf);