From c13b2633f49e3e61b37973204793a4d9ef981175 Mon Sep 17 00:00:00 2001 From: Daniel Barkalow Date: Sat, 26 Apr 2008 15:53:09 -0400 Subject: Make walker.fetch_ref() take a struct ref. This simplifies a few things, makes a few things slightly more complicated, but, more importantly, allows that, when struct ref can represent a symref, http_fetch_ref() can return one. Incidentally makes the string that http_fetch_ref() gets include "refs/" (if appropriate), because that's how the name field of struct ref works. As far as I can tell, the usage in walker:interpret_target() wouldn't have worked previously, if it ever would have been used, which it wouldn't (since the fetch process uses the hash instead of the name of the ref there). Signed-off-by: Daniel Barkalow Signed-off-by: Junio C Hamano --- http.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'http.c') diff --git a/http.c b/http.c index 256a5f15f4..c8df13b8ae 100644 --- a/http.c +++ b/http.c @@ -589,8 +589,9 @@ static char *quote_ref_url(const char *base, const char *ref) len += 2; /* extra two hex plus replacement % */ qref = xmalloc(len); memcpy(qref, base, baselen); - memcpy(qref + baselen, "/refs/", 6); - for (cp = ref, dp = qref + baselen + 6; (ch = *cp) != 0; cp++) { + dp = qref + baselen; + *(dp++) = '/'; + for (cp = ref; (ch = *cp) != 0; cp++) { if (needs_quote(ch)) { *dp++ = '%'; *dp++ = hex((ch >> 4) & 0xF); @@ -604,7 +605,7 @@ static char *quote_ref_url(const char *base, const char *ref) return qref; } -int http_fetch_ref(const char *base, const char *ref, unsigned char *sha1) +int http_fetch_ref(const char *base, struct ref *ref) { char *url; struct strbuf buffer = STRBUF_INIT; @@ -612,7 +613,7 @@ int http_fetch_ref(const char *base, const char *ref, unsigned char *sha1) struct slot_results results; int ret; - url = quote_ref_url(base, ref); + url = quote_ref_url(base, ref->name); slot = get_active_slot(); slot->results = &results; curl_easy_setopt(slot->curl, CURLOPT_FILE, &buffer); @@ -624,12 +625,12 @@ int http_fetch_ref(const char *base, const char *ref, unsigned char *sha1) if (results.curl_result == CURLE_OK) { strbuf_rtrim(&buffer); if (buffer.len == 40) - ret = get_sha1_hex(buffer.buf, sha1); + ret = get_sha1_hex(buffer.buf, ref->old_sha1); else ret = 1; } else { ret = error("Couldn't get %s for %s\n%s", - url, ref, curl_errorstr); + url, ref->name, curl_errorstr); } } else { ret = error("Unable to start request"); -- cgit v1.3 From be885d96fe0ebed47e637f3b0dd24fc5902f7081 Mon Sep 17 00:00:00 2001 From: Daniel Barkalow Date: Sat, 26 Apr 2008 15:53:12 -0400 Subject: 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(-) (limited to 'http.c') 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; } -- cgit v1.3