git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: git@vger.kernel.org
Subject: [PATCH 4/5] upload-pack: implement protocol extension "symbolic-ref"
Date: Sun, 30 Nov 2008 01:57:29 -0800	[thread overview]
Message-ID: <1228039053-31099-2-git-send-email-gitster@pobox.com> (raw)
In-Reply-To: <1228039053-31099-1-git-send-email-gitster@pobox.com>

This extends the fetch-pack protocol to allow the receiving end to ask
which actual ref each symbolic ref points at.

Although the new capability is advertised on the first available ref in
the same way as the other extensions, the way to trigger this extension
from the receiving end is not by adding it in the first "want" line as
usual.  Instead, the receiving end sends a "symbolic-ref" request packet
before the usual sequence of "want" lines.

This is unfortunate because it forces an extra round trip (receiving end
sends a "please tell me symbolic-ref" packet, and then upload side sends
"here are the requested information" packet), but it has to be implemented
this way because (1) ls-remote may need to ask for this information, in
which case there is no "want" to be sent; and (2) the transport API
insists that transport_get_remote_refs() returns the final list, and does
not allow augmenting what was initially obtained from the call to it by
later calls to transport_fetch_refs() easily.

It also is unfortunate that with this change on the server side, older
clients running "ls-remote" without actually downloading anything will
trigger "The remote end hung up unexpectedly" error on the uploading side,
which is annoying even though it is benign.  You can observe it by applying
only this patch but not the patch to the receiving end and running t5601
under "sh -x".

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

diff --git a/upload-pack.c b/upload-pack.c
index 4029019..a925f69 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -494,6 +494,23 @@ static void exchange_shallows(int depth, struct object_array *shallows)
 		}
 }
 
+static int one_symref_info(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
+{
+	if ((flag & REF_ISSYMREF)) {
+		unsigned char dummy[20];
+		const char *target = resolve_ref(refname, dummy, 0, NULL);
+		packet_write(1, "symref %s %s", refname, target);
+	}
+	return 0;
+}
+
+static void send_symref_info(void)
+{
+	head_ref(one_symref_info, NULL);
+	for_each_ref(one_symref_info, NULL);
+	packet_flush(1);
+}
+
 static void receive_needs(void)
 {
 	struct object_array shallows = {0, 0, NULL};
@@ -502,11 +519,29 @@ static void receive_needs(void)
 
 	if (debug_fd)
 		write_in_full(debug_fd, "#S\n", 3);
-	for (;;) {
+
+	/*
+	 * This is very unfortunate, but the "transport" abstraction
+	 * is screwed up and insists that getting the list of refs
+	 * to finish before actually sending the "needs" list from
+	 * the client end.
+	 */
+	len = packet_read_line(0, line, sizeof(line));
+	if (len) {
+		if (!prefixcmp(line, "symbolic-ref")) {
+			reset_timeout();
+			send_symref_info();
+			len = 0;
+		}
+	}
+	for (;; len = 0) {
 		struct object *o;
 		unsigned char sha1_buf[20];
-		len = packet_read_line(0, line, sizeof(line));
-		reset_timeout();
+
+		if (!len) {
+			len = packet_read_line(0, line, sizeof(line));
+			reset_timeout();
+		}
 		if (!len)
 			break;
 		if (debug_fd)
@@ -577,7 +612,7 @@ static void receive_needs(void)
 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"
-		" side-band-64k ofs-delta shallow no-progress"
+		" side-band-64k ofs-delta shallow no-progress symbolic-ref"
 		" include-tag";
 	struct object *o = parse_object(sha1);
 
-- 
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 ` Junio C Hamano [this message]
2008-11-30  9:57   ` [PATCH 3/5] clone: find the current branch more explicitly Junio C Hamano
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

  List information: http://vger.kernel.org/majordomo-info.html

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

  git send-email \
    --in-reply-to=1228039053-31099-2-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.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

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 read-only IMAP folder(s) and NNTP newsgroup(s).