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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxx>
---
 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

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux