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

[PATCH 4/5] upload-pack: implement protocol extension "symbolic-ref"

From
Junio C Hamano <gitster@pobox.com>
Date
Nov 30, 2008, 09:57 UTC
Message-ID
<1228039053-31099-2-git-send-email-gitster@pobox.com>
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
Previous: Junio C HamanoNext: Junio C Hamano
Message 2 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.