From be885d96fe0ebed47e637f3b0dd24fc5902f7081 Mon Sep 17 00:00:00 2001 From: Daniel Barkalow Date: Sat, 26 Apr 2008 15:53:12 -0400 Subject: [PATCH] Make ls-remote http://... list HEAD, like for git://... 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 Signed-off-by: Junio C Hamano --- 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 3fcc283002..cfc123747c 100644 --- a/cache.h +++ b/cache.h @@ -634,6 +634,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 c8df13b8ae..acf746a12d 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 2d9af4023e..1504cd01e8 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; } } @@ -1172,3 +1181,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 a38774bbdc..ab8230850c 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 393e0e8fe2..b012a28338 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; }