git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 3/5] clone: find the current branch more explicitly

From
Junio C Hamano <gitster@pobox.com>
Date
Nov 30, 2008, 09:57 UTC
Message-ID
<1228039053-31099-3-git-send-email-gitster@pobox.com>
In-Reply-To
<1228039053-31099-2-git-send-email-gitster@pobox.com>

This makes "git clone" use the symbolic-ref protocol extension to find the ref the HEAD is pointing at (when available), so that it can point at the current branch that is not 'master' but happens to point at the same commit as 'master'. IOW, immediately after doing the following:

    $ git checkout -b another master

a clone made out of that repository will check out 'another' branch, not 'master'.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin-clone.c |   24 +++++++++++++++++++-----
 connect.c       |   36 ++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+), 5 deletions(-)
diff --git a/builtin-clone.c b/builtin-clone.c
index 2feac9c..a8b8d56 100644
--- a/builtin-clone.c
+++ b/builtin-clone.c
@@ -299,13 +299,27 @@ static const struct ref *locate_head(const struct ref *refs,
 	const struct ref *remote_head = NULL;
 	const struct ref *remote_master = NULL;
 	const struct ref *r;
-	for (r = refs; r; r = r->next)
-		if (!strcmp(r->name, "HEAD"))
+
+	for (r = refs; r; r = r->next) {
+		if (!strcmp(r->name, "HEAD")) {
 			remote_head = r;
+			break;
+		}
+	}
 
-	for (r = mapped_refs; r; r = r->next)
-		if (!strcmp(r->name, "refs/heads/master"))
-			remote_master = r;
+	if (remote_head && remote_head->symref) {
+		for (r = mapped_refs; r; r = r->next)
+			if (!strcmp(r->name, remote_head->symref)) {
+				remote_master = r;
+				break;
+			}
+	}
+
+	if (!remote_master) {
+		for (r = mapped_refs; r; r = r->next)
+			if (!strcmp(r->name, "refs/heads/master"))
+				remote_master = r;
+	}
 
 	if (remote_head_p)
 		*remote_head_p = remote_head;
diff --git a/connect.c b/connect.c
index 402fbe6..40b43b4 100644
--- a/connect.c
+++ b/connect.c
@@ -48,6 +48,39 @@ static void add_extra_have(struct extra_have_objects *extra, unsigned char *sha1
 	extra->nr++;
 }
 
+static void receive_symref(int fd[2], struct ref *refs)
+{
+	char line[1024];
+	int len;
+
+	packet_write(fd[1], "symbolic-ref");
+	while ((len = packet_read_line(fd[0], line, sizeof(line)))) {
+		if (!prefixcmp(line, "symref ")) {
+			struct ref *sym;
+			char *symref = line + 7;
+			char *target = strchr(symref, ' ');
+			if (!target)
+				die("Malformed symref line %s", line);
+			*target++ = '\0';
+			sym = find_ref_by_name(refs, symref);
+			if (!sym) {
+				/*
+				 * NEEDSWORK: perhaps create the symref ref
+				 * that is still unborn and queue it?
+				 */
+				continue;
+			}
+			if (sym->symref)
+				die("symref line says %s points at %s "
+				    "but earlier it said it points at %s",
+				    symref, target, sym->symref);
+			sym->symref = xstrdup(target);
+			continue;
+		}
+		die("expected symref, got %s", line);
+	}
+}
+
 /*
  * Read all the refs from the other end
  */
@@ -56,6 +89,7 @@ struct ref **get_remote_heads(int fd[2], struct ref **list,
 			      unsigned int flags,
 			      struct extra_have_objects *extra_have)
 {
+	struct ref **original_list = list;
 	*list = NULL;
 	for (;;) {
 		struct ref *ref;
@@ -98,6 +132,8 @@ struct ref **get_remote_heads(int fd[2], struct ref **list,
 		*list = ref;
 		list = &ref->next;
 	}
+	if (server_supports("symbolic-ref"))
+		receive_symref(fd, *original_list);
 	return list;
 }
 
-- 
1.6.0.4.850.g6bd829
Previous: Junio C HamanoNext: Junio C Hamano
Message 3 of 11 in “clone: test the new HEAD detection logic”
  1. 5/5 clone: test the new HEAD detection logicJunio C Hamano, Nov 30, 2008
  2. 4/5 upload-pack: implement protocol extension "symbolic-ref"Junio C Hamano, Nov 30, 2008
  3. 3/5 clone: find the current branch more explicitlyJunio C Hamano, Nov 30, 2008
  4. 2/5 get_remote_heads(): do not assume that the conversation is one-wayJunio C Hamano, Nov 30, 2008
  5. 1/5 upload-pack.c: refactor receive_needs()Junio C Hamano, Nov 30, 2008
  6. 0/5 Detecting HEAD more reliably while cloningJunio C Hamano, Nov 30, 2008
  7. Junio C HamanoNov 30, 2008
  8. Junio C HamanoDec 1, 2008
  9. Jeff KingNov 30, 2008
  10. Jeff KingNov 30, 2008
  11. Junio C HamanoDec 1, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.