git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: git@vger.kernel.org
Subject: [PATCH 3/5] clone: find the current branch more explicitly
Date: Sun, 30 Nov 2008 01:57:30 -0800	[thread overview]
Message-ID: <1228039053-31099-3-git-send-email-gitster@pobox.com> (raw)
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

  reply	other threads:[~2008-11-30  9:59 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-11-30  9:57 [PATCH 5/5] clone: test the new HEAD detection logic Junio C Hamano
2008-11-30  9:57 ` [PATCH 4/5] upload-pack: implement protocol extension "symbolic-ref" Junio C Hamano
2008-11-30  9:57   ` Junio C Hamano [this message]
2008-11-30  9:57     ` [PATCH 2/5] get_remote_heads(): do not assume that the conversation is one-way Junio C Hamano
2008-11-30  9:57       ` [PATCH 1/5] upload-pack.c: refactor receive_needs() Junio C Hamano
2008-11-30  9:57         ` [PATCH 0/5] Detecting HEAD more reliably while cloning Junio C Hamano
2008-11-30 10:04           ` Junio C Hamano
2008-12-01  2:54             ` Junio C Hamano
2008-11-30 18:10     ` [PATCH 3/5] clone: find the current branch more explicitly Jeff King
2008-11-30 18:02   ` [PATCH 4/5] upload-pack: implement protocol extension "symbolic-ref" Jeff King
2008-12-01 14:03     ` Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1228039053-31099-3-git-send-email-gitster@pobox.com \
    --to=gitster@pobox.com \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).