shithub: git9

Download patch

ref: bc702cb015b3c2903ee03f5adf2852fc926633ed
parent: 5030185c312fbac20bcee810f62b60dbfc635ee0
author: Ori Bernstein <ori@eigenstate.org>
date: Fri Jan 29 18:10:45 EST 2021

git/send, git/serve: fix branch deletion

We didn't correctly delete branches, fix it.

--- a/send.c
+++ b/send.c
@@ -57,10 +57,15 @@
 			pfx = "";
 		if((r = smprint("%s%s", pfx, removed[i])) == nil)
 			sysfatal("smprint: %r");
-		if((idx = findref(ref, nu, r)) != -1)
-			memcpy(&tail[idx], &Zhash, sizeof(Hash));
+		if((idx = findref(ref, nu, r)) == -1)
+			idx = nu++;
+		assert(idx < nbranch);
+		memcpy(&tail[idx], &Zhash, sizeof(Hash));
 		free(r);
 	}
+	dprint(1, "nu: %d\n", nu);
+	for(i = 0; i < nu; i++)
+		dprint(1, "update: %H %s\n", tail[i], ref[i]);
 	*tailp = tail;
 	*refp = ref;
 	return nu;	
@@ -134,7 +139,7 @@
 		send=1;
 	for(i = 0; i < nupd; i++){
 		a = readobject(theirs[i]);
-		b = readobject(ours[i]);
+		b = hasheq(&ours[i], &Zhash) ? nil : readobject(ours[i]);
 		p = nil;
 		if(a != nil && b != nil)
 			p = ancestor(a, b);
@@ -147,10 +152,6 @@
 		unref(a);
 		unref(b);
 		unref(p);
-		if(hasheq(&ours[i], &Zhash)){
-			print("removed %s\n", refs[i]);
-			continue;
-		}
 		if(hasheq(&theirs[i], &ours[i])){
 			print("uptodate %s\n", refs[i]);
 			continue;
@@ -174,12 +175,7 @@
 		}
 		if(writepkt(c, buf, n) == -1)
 			sysfatal("unable to send update pkt");
-		/*
-		 * If we're rolling back with a force push, the other side already
-		 * has our changes. There's no need to send a pack if that's the case.
-		 */
-		if(a == nil || b == nil || ancestor(b, a) != b)
-			send = 1;
+		send = 1;
 	}
 	flushpkt(c);
 	if(!send){
--- a/serve.c
+++ b/serve.c
@@ -390,6 +390,14 @@
 				goto error;
 			}
 		}
+		if(snprint(refpath, sizeof(refpath), ".git/%s", ref[i]) == sizeof(refpath)){
+			werrstr("ref path too long: %s", ref[i]);
+			goto error;
+		}
+		if(hasheq(&upd[i], &Zhash)){
+			remove(refpath);
+			continue;
+		}
 		if((o = readobject(upd[i])) == nil){
 			werrstr("update to nonexistent hash %H", upd[i]);
 			goto error;
@@ -403,10 +411,6 @@
 			newidx = i;
 		}
 		unref(o);
-		if(snprint(refpath, sizeof(refpath), ".git/%s", ref[i]) == sizeof(refpath)){
-			werrstr("ref path too long: %s", ref[i]);
-			goto error;
-		}
 		if((fd = create(refpath, OWRITE|OTRUNC, 0644)) == -1){
 			werrstr("open ref: %r");
 			goto error;