shithub: git9

Download patch

ref: 22e39fb1faaa0398d49a83e960536f80fe803895
parent: b373c36d4caecfdbcd6d0833c11092893fcb770c
author: Ori Bernstein <ori@eigenstate.org>
date: Wed Oct 21 13:35:27 EDT 2020

clone: use symbolic refs, only create tags and branches

Now we should end up with the correct default branch in
(almost) all cases, and skips all refs that do not start
with 'refs/heads' or 'refs/tags'.

--- a/clone
+++ b/clone
@@ -33,13 +33,23 @@
 		echo '	fetch=+refs/heads/*:refs/remotes/origin/*'
 	}
 	{git/fetch $debug $remote >[2=3] | awk '
-		/^remote/{
+		BEGIN{
+			headref=""
+			headhash=""
+		}
+		/^symref /{
+			if($2 == "HEAD"){
+				gsub("^refs/heads", "refs/remotes/origin", $3)
+				gsub("^refs/tags", "refs/remotes/origin/tags", $3)
+				headref=$3
+			}
+		}
+		/^remote /{
 			if($2=="HEAD"){
 				headhash=$3
-				headref=""
-			}else{
+			}else if(match($2, "^refs/(heads|tags)/")){
 				gsub("^refs/heads", "refs/remotes/origin", $2)
-				if($2 == "refs/remotes/origin/master" || $3 == headhash)
+				if($2 == headref || (headref == "" && $3 == headhash))
 					headref=$2
 				outfile = ".git/" $2
 				outdir = outfile
--- a/fetch.c
+++ b/fetch.c
@@ -135,12 +135,39 @@
 	return strcmp(br, name) == 0;
 }
 
+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
+handlecaps(char *caps)
+{
+	char *p, *n, *c, *r;
+
+	for(p = caps; p != nil; p = n){
+		n = strchr(p, ' ');
+		if(n != nil)
+			*n++ = 0;
+		if((c = matchcap(p, "symref=", 0)) != nil){
+			if((r = strchr(c, ':')) != nil){
+				*r++ = '\0';
+				print("symref %s %s\n", c, r);
+			}
+		}
+	}
+}
+
 int
 fetchpack(Conn *c, int pfd, char *packtmp)
 {
 	char buf[Pktmax], idxtmp[256], *sp[3];
 	Hash h, *have, *want;
-	int nref, refsz;
+	int nref, refsz, first;
 	int i, n, req;
 	vlong packsz;
 	Object *o;
@@ -147,6 +174,7 @@
 
 	nref = 0;
 	refsz = 16;
+	first = 1;
 	have = emalloc(refsz * sizeof(have[0]));
 	want = emalloc(refsz * sizeof(want[0]));
 	while(1){
@@ -157,6 +185,11 @@
 			break;
 		if(strncmp(buf, "ERR ", 4) == 0)
 			sysfatal("%s", buf + 4);
+
+		if(first && n > strlen(buf))
+			handlecaps(buf + strlen(buf) + 1);
+		first = 0;
+
 		getfields(buf, sp, nelem(sp), 1, " \t\n\r");
 		if(strstr(sp[1], "^{}"))
 			continue;