shithub: git9

Download patch

ref: 5fe5553163e4e5aea41ea6b6e89136e7ea9ce339
parent: 099825acc6231c700ee53359f3fb80dfb5a83eee
author: Ori Bernstein <ori@eigenstate.org>
date: Mon May 31 20:16:20 EDT 2021

git/send: pick minimal delta set correctly (thanks igor)

We weren't giving all objects to the twixt() function, and
it was making bad life choices -- gambling, smoking, drinking,
and packing in too much data.

With more information, it doesn't do the last.

--- a/pack.c
+++ b/pack.c
@@ -1326,7 +1326,7 @@
 	if(t->type != GTree){
 		fprint(2, "load: %H: not tree\n", t->hash);
 		unref(t);
-		return -1;
+		return 0;
 	}
 	addmeta(v, has, t, dpath, mtime);
 	for(i = 0; i < t->tree->nent; i++){
@@ -1363,7 +1363,7 @@
 	if(c->type != GCommit){
 		fprint(2, "load: %H: not commit\n", c->hash);
 		unref(c);
-		return -1;
+		return 0;
 	}
 	addmeta(v, has, c, "", c->commit->ctime);
 	r = loadtree(v, has, c->commit->tree, "", c->commit->ctime);
--- a/ref.c
+++ b/ref.c
@@ -294,11 +294,11 @@
 		if(hasheq(&tail[i], &Zhash))
 			continue;
 		if((o = readobject(tail[i])) == nil){
-			fprint(2, "warning: %H does not point at commit\n", o->hash);
 			werrstr("read tail %H: %r", tail[i]);
 			return -1;
 		}
 		if(o->type != GCommit){
+			fprint(2, "warning: %H does not point at commit\n", o->hash);
 			unref(o);
 			continue;
 		}
--- a/send.c
+++ b/send.c
@@ -4,6 +4,7 @@
 #include "git.h"
 
 typedef struct Capset	Capset;
+typedef struct Map	Map;
 
 struct Capset {
 	int	sideband;
@@ -11,6 +12,12 @@
 	int	report;
 };
 
+struct Map {
+	char	*ref;
+	Hash	ours;
+	Hash	theirs;
+};
+
 int sendall;
 int force;
 int nbranch;
@@ -24,7 +31,6 @@
 findref(char **r, int nr, char *ref)
 {
 	int i;
-
 	for(i = 0; i < nr; i++)
 		if(strcmp(r[i], ref) == 0)
 			return i;
@@ -32,6 +38,16 @@
 }
 
 int
+findkey(Map *m, int nm, char *ref)
+{
+	int i;
+	for(i = 0; i < nm; i++)
+		if(strcmp(m[i].ref, ref) == 0)
+			return i;
+	return -1;
+}
+
+int
 readours(Hash **tailp, char ***refp)
 {
 	int nu, i, idx;
@@ -101,17 +117,27 @@
 int
 sendpack(Conn *c)
 {
-	int i, n, idx, nupd, nsp, send, first;
+	int i, n, idx, nsp, send, first;
+	int nours, ntheirs, nmap;
 	char buf[Pktmax], *sp[3];
 	Hash h, *theirs, *ours;
 	Object *a, *b, *p;
 	char **refs;
 	Capset cs;
+	Map *map, *m;
 
 	first = 1;
 	memset(&cs, 0, sizeof(Capset));
-	nupd = readours(&ours, &refs);
-	theirs = eamalloc(nupd, sizeof(Hash));
+	nours = readours(&ours, &refs);
+	theirs = nil;
+	ntheirs = 0;
+	nmap = nours;
+	map = eamalloc(nmap, sizeof(Map));
+	for(i = 0; i < nmap; i++){
+		map[i].ours = ours[i];
+		map[i].theirs = Zhash;
+		map[i].ref = refs[i];
+	}
 	while(1){
 		n = readpkt(c, buf, sizeof(buf));
 		if(n == -1)
@@ -126,10 +152,12 @@
 
 		if(getfields(buf, sp, nelem(sp), 1, " \t\r\n") != 2)
 			sysfatal("invalid ref line %.*s", utfnlen(buf, n), buf);
-		if((idx = findref(refs, nupd, sp[1])) == -1)
-			continue;
-		if(hparse(&theirs[idx], sp[0]) == -1)
+		theirs = earealloc(theirs, ntheirs+1, sizeof(Hash));
+		if(hparse(&theirs[ntheirs], sp[0]) == -1)
 			sysfatal("invalid hash %s", sp[0]);
+		if((idx = findkey(map, nmap, sp[1])) != -1)
+			map[idx].theirs = theirs[ntheirs];
+		ntheirs++;
 	}
 
 	if(writephase(c) == -1)
@@ -137,13 +165,17 @@
 	send = 0;
 	if(force)
 		send=1;
-	for(i = 0; i < nupd; i++){
-		a = readobject(theirs[i]);
-		b = hasheq(&ours[i], &Zhash) ? nil : readobject(ours[i]);
+	for(i = 0; i < nmap; i++){
+		m = &map[i];
+		a = readobject(m->theirs);
+		if(hasheq(&m->ours, &Zhash))
+			b = nil;
+		else
+			b = readobject(m->ours);
 		p = nil;
 		if(a != nil && b != nil)
 			p = ancestor(a, b);
-		if(!force && !hasheq(&theirs[i], &Zhash) && (a == nil || p != a)){
+		if(!force && !hasheq(&m->theirs, &Zhash) && (a == nil || p != a)){
 			fprint(2, "remote has diverged\n");
 			werrstr("force needed");
 			flushpkt(c);
@@ -152,12 +184,12 @@
 		unref(a);
 		unref(b);
 		unref(p);
-		if(hasheq(&theirs[i], &ours[i])){
-			print("uptodate %s\n", refs[i]);
+		if(hasheq(&m->theirs, &m->ours)){
+			print("uptodate %s\n", m->ref);
 			continue;
 		}
-		print("update %s %H %H\n", refs[i], theirs[i], ours[i]);
-		n = snprint(buf, sizeof(buf), "%H %H %s", theirs[i], ours[i], refs[i]);
+		print("update %s %H %H\n", m->ref, m->theirs, m->ours);
+		n = snprint(buf, sizeof(buf), "%H %H %s", m->theirs, m->ours, m->ref);
 
 		/*
 		 * Workaround for github.
@@ -183,7 +215,7 @@
 		return 0;
 	}
 
-	if(writepack(c->wfd, ours, nupd, theirs, nupd, &h) == -1)
+	if(writepack(c->wfd, ours, nours, theirs, ntheirs, &h) == -1)
 		return -1;
 	if(!cs.report)
 		return 0;