[PATCH 2/2] Make ls-remote http://... list HEAD, like for git://...

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

 



This makes a struct ref able to represent a symref, and makes http.c
able to recognize one, and makes transport.c look for "HEAD" as a ref
in the list, and makes it dereference symrefs for the resulting ref,
if any.

Signed-off-by: Daniel Barkalow <barkalow@xxxxxxxxxxxx>
---
Getting HEAD for HTTP turns out to be surprisingly tricky. First, you need 
to look for it explicitly, because it's not in info/refs. Then, it's 
normally a symref, so you have to be able to handle that as a response. 
And you don't have the list of things it can reference at that point in 
the code.

In any case, it will be useful to be able to have the response from 
transport_get_remote_refs() able to mention that HEAD is a symref, and 
what it links to, so that the HEAD detection can use the remote repo's 
actual information (instead of guessing) when the remote repo provides 
that information.

 cache.h     |    1 +
 http.c      |    5 ++++-
 remote.c    |   23 ++++++++++++++++++++++-
 remote.h    |    2 ++
 transport.c |   14 ++++++++++++++
 5 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/cache.h b/cache.h
index 50b28fa..7674277 100644
--- a/cache.h
+++ b/cache.h
@@ -624,6 +624,7 @@ struct ref {
 	struct ref *next;
 	unsigned char old_sha1[20];
 	unsigned char new_sha1[20];
+	char *symref;
 	unsigned int force:1,
 		merge:1,
 		nonfastforward:1,
diff --git a/http.c b/http.c
index c8df13b..acf746a 100644
--- a/http.c
+++ b/http.c
@@ -626,7 +626,10 @@ int http_fetch_ref(const char *base, struct ref *ref)
 			strbuf_rtrim(&buffer);
 			if (buffer.len == 40)
 				ret = get_sha1_hex(buffer.buf, ref->old_sha1);
-			else
+			else if (!prefixcmp(buffer.buf, "ref: ")) {
+				ref->symref = xstrdup(buffer.buf + 5);
+				ret = 0;
+			} else
 				ret = 1;
 		} else {
 			ret = error("Couldn't get %s for %s\n%s",
diff --git a/remote.c b/remote.c
index 06ad156..a54f0f7 100644
--- a/remote.c
+++ b/remote.c
@@ -706,13 +706,22 @@ struct ref *copy_ref_list(const struct ref *ref)
 	return ret;
 }
 
+void free_ref(struct ref *ref)
+{
+	if (!ref)
+		return;
+	free(ref->remote_status);
+	free(ref->symref);
+	free(ref);
+}
+
 void free_refs(struct ref *ref)
 {
 	struct ref *next;
 	while (ref) {
 		next = ref->next;
 		free(ref->peer_ref);
-		free(ref);
+		free_ref(ref);
 		ref = next;
 	}
 }
@@ -1146,3 +1155,15 @@ int get_fetch_map(const struct ref *remote_refs,
 
 	return 0;
 }
+
+int resolve_remote_symref(struct ref *ref, struct ref *list)
+{
+	if (!ref->symref)
+		return 0;
+	for (; list; list = list->next)
+		if (!strcmp(ref->symref, list->name)) {
+			hashcpy(ref->old_sha1, list->old_sha1);
+			return 0;
+		}
+	return 1;
+}
diff --git a/remote.h b/remote.h
index a38774b..ab82308 100644
--- a/remote.h
+++ b/remote.h
@@ -62,6 +62,8 @@ int check_ref_type(const struct ref *ref, int flags);
  */
 void free_refs(struct ref *ref);
 
+int resolve_remote_symref(struct ref *ref, struct ref *list);
+
 /*
  * Removes and frees any duplicate refs in the map.
  */
diff --git a/transport.c b/transport.c
index 393e0e8..b012a28 100644
--- a/transport.c
+++ b/transport.c
@@ -441,10 +441,14 @@ static struct ref *get_refs_via_curl(struct transport *transport)
 	struct ref *ref = NULL;
 	struct ref *last_ref = NULL;
 
+	struct walker *walker;
+
 	if (!transport->data)
 		transport->data = get_http_walker(transport->url,
 						transport->remote);
 
+	walker = transport->data;
+
 	refs_url = xmalloc(strlen(transport->url) + 11);
 	sprintf(refs_url, "%s/info/refs", transport->url);
 
@@ -500,6 +504,16 @@ static struct ref *get_refs_via_curl(struct transport *transport)
 
 	strbuf_release(&buffer);
 
+	ref = alloc_ref(strlen("HEAD") + 1);
+	strcpy(ref->name, "HEAD");
+	if (!walker->fetch_ref(walker, ref) &&
+	    !resolve_remote_symref(ref, refs)) {
+		ref->next = refs;
+		refs = ref;
+	} else {
+		free(ref);
+	}
+
 	return refs;
 }
 
-- 
1.5.4.3.610.gea6cd
--
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