diff options
-rw-r--r-- | cache.h | 1 | ||||
-rw-r--r-- | http.c | 5 | ||||
-rw-r--r-- | remote.c | 23 | ||||
-rw-r--r-- | remote.h | 2 | ||||
-rw-r--r-- | transport.c | 14 |
5 files changed, 43 insertions, 2 deletions
@@ -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, @@ -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", @@ -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; +} @@ -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 393e0e8fe..b012a2833 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; } |