All of lore.kernel.org
 help / color / mirror / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: git@vger.kernel.org
Cc: Andreas Krey <a.krey@gmx.de>
Subject: [PATCH v2 2/6] upload-pack: send symbolic ref information as capability
Date: Tue, 17 Sep 2013 19:31:25 -0700	[thread overview]
Message-ID: <1379471489-26280-3-git-send-email-gitster@pobox.com> (raw)
In-Reply-To: <1379471489-26280-1-git-send-email-gitster@pobox.com>

One long-standing flaw in the pack transfer protocol was that there
was no way to tell the other end which branch "HEAD" points at.
With a new "sym" capability (e.g. "sym=HEAD:refs/heads/master"; can
be repeated more than once to represent symbolic refs other than
HEAD, such as "refs/remotes/origin/HEAD").

Add an infrastructure to collect symbolic refs, format them as extra
capabilities and put it on the wire.  For now, just send information
on the "HEAD" and nothing else.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 upload-pack.c | 48 +++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 43 insertions(+), 5 deletions(-)

diff --git a/upload-pack.c b/upload-pack.c
index a6e107f..53958b9 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -734,6 +734,16 @@ static int mark_our_ref(const char *refname, const unsigned char *sha1, int flag
 	return 0;
 }
 
+static void format_symref_info(struct strbuf *buf, struct string_list *symref)
+{
+	struct string_list_item *item;
+
+	if (!symref->nr)
+		return;
+	for_each_string_list_item(item, symref)
+		strbuf_addf(buf, " sym=%s:%s", item->string, (char *)item->util);
+}
+
 static int send_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
 {
 	static const char *capabilities = "multi_ack thin-pack side-band"
@@ -745,32 +755,60 @@ static int send_ref(const char *refname, const unsigned char *sha1, int flag, vo
 	if (mark_our_ref(refname, sha1, flag, NULL))
 		return 0;
 
-	if (capabilities)
-		packet_write(1, "%s %s%c%s%s%s agent=%s\n",
+	if (capabilities) {
+		struct strbuf symref_info = STRBUF_INIT;
+
+		format_symref_info(&symref_info, cb_data);
+		packet_write(1, "%s %s%c%s%s%s%s agent=%s\n",
 			     sha1_to_hex(sha1), refname_nons,
 			     0, capabilities,
 			     allow_tip_sha1_in_want ? " allow-tip-sha1-in-want" : "",
 			     stateless_rpc ? " no-done" : "",
+			     symref_info.buf,
 			     git_user_agent_sanitized());
-	else
+		strbuf_release(&symref_info);
+	} else {
 		packet_write(1, "%s %s\n", sha1_to_hex(sha1), refname_nons);
+	}
 	capabilities = NULL;
 	if (!peel_ref(refname, peeled))
 		packet_write(1, "%s %s^{}\n", sha1_to_hex(peeled), refname_nons);
 	return 0;
 }
 
+static int find_symref(const char *refname, const unsigned char *sha1, int flag,
+		       void *cb_data)
+{
+	const char *symref_target;
+	struct string_list_item *item;
+	unsigned char unused[20];
+
+	if ((flag & REF_ISSYMREF) == 0)
+		return 0;
+	symref_target = resolve_ref_unsafe(refname, unused, 0, &flag);
+	if (!symref_target || (flag & REF_ISSYMREF) == 0)
+		die("'%s' is a symref but it is not?", refname);
+	item = string_list_append(cb_data, refname);
+	item->util = xstrdup(symref_target);
+	return 0;
+}
+
 static void upload_pack(void)
 {
+	struct string_list symref = STRING_LIST_INIT_DUP;
+
+	head_ref_namespaced(find_symref, &symref);
+
 	if (advertise_refs || !stateless_rpc) {
 		reset_timeout();
-		head_ref_namespaced(send_ref, NULL);
+		head_ref_namespaced(send_ref, &symref);
 		for_each_namespaced_ref(send_ref, NULL);
 		packet_flush(1);
 	} else {
-		head_ref_namespaced(mark_our_ref, NULL);
+		head_ref_namespaced(mark_our_ref, &symref);
 		for_each_namespaced_ref(mark_our_ref, NULL);
 	}
+	string_list_clear(&symref, 1);
 	if (advertise_refs)
 		return;
 
-- 
1.8.4-585-g8d1dcaf

  parent reply	other threads:[~2013-09-18  2:31 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-09-06 15:52 [PATCH 0/3] Unconfuse git clone when two branches at are HEAD Andreas Krey
2013-09-06 15:56 ` [PATCH 1/3] upload-pack: send the HEAD information Andreas Krey
2013-09-06 17:46   ` Junio C Hamano
2013-09-06 19:29     ` Andreas Krey
2013-09-06 19:54       ` Junio C Hamano
2013-09-08  7:13     ` Jeff King
2013-09-08  7:22       ` Jeff King
2013-09-08 17:27       ` Junio C Hamano
2013-09-18  2:31   ` [PATCH v2 0/6] Removing the guesswork of HEAD in "clone" Junio C Hamano
2013-09-18  2:31     ` [PATCH v2 1/6] upload-pack.c: do not pass confusing cb_data to mark_our_ref() Junio C Hamano
2013-09-18  2:31     ` Junio C Hamano [this message]
2013-09-18  4:36       ` [PATCH v2 2/6] upload-pack: send symbolic ref information as capability Junio C Hamano
2013-09-18  2:31     ` [PATCH v2 3/6] upload-pack: send non-HEAD symbolic refs Junio C Hamano
2013-09-18  2:31     ` [PATCH v2 4/6] connect.c: make parse_feature_value() static Junio C Hamano
2013-09-18  2:31     ` [PATCH v2 5/6] connect: annotate refs with their symref information in get_remote_head() Junio C Hamano
2013-09-18  2:31     ` [PATCH v2 6/6] clone: test the new HEAD detection logic Junio C Hamano
2013-09-06 15:56 ` [PATCH 2/3] connect.c: save symref info from server capabilities Andreas Krey
2013-09-06 17:56   ` Junio C Hamano
2013-09-06 19:25     ` Andreas Krey
2013-09-06 19:46       ` Junio C Hamano
2013-09-06 15:57 ` [PATCH 3/3] clone: test the new HEAD detection logic Andreas Krey
2013-09-06 17:29 ` [PATCH 0/3] Unconfuse git clone when two branches at are HEAD Philip Oakley
2013-09-06 18:17   ` Junio C Hamano
2013-09-06 23:19     ` Philip Oakley
2013-09-07 15:50       ` Junio C Hamano
2013-09-07 19:19         ` Philip Oakley
2013-09-08 17:35           ` Junio C Hamano
2013-09-08 21:00             ` Philip Oakley
2013-09-09 14:44               ` Junio C Hamano
2013-09-09 16:08                 ` Andreas Krey
2013-09-09 22:20                 ` Philip Oakley
2013-09-09 22:26                   ` 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=1379471489-26280-3-git-send-email-gitster@pobox.com \
    --to=gitster@pobox.com \
    --cc=a.krey@gmx.de \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.