@matheusbsbs / matheus-bagliano / commits / be885d96fe
Fork 0

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 <barkalow@iabervon.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Daniel Barkalow committed Apr 26, 2008 at 15:53 UTC be885d96fe0ebed47e637f3b0dd24fc5902f7081
5 files changed +43 -2
cache.h
+1
@@ -634,6 +634,7 @@ struct ref {
634 struct ref *next;
635 unsigned char old_sha1[20];
636 unsigned char new_sha1[20];
637 + char *symref;
638 unsigned int force:1,
639 merge:1,
640 nonfastforward:1,
http.c
+4 -1
@@ -626,7 +626,10 @@ int http_fetch_ref(const char *base, struct ref *ref)
626 strbuf_rtrim(&buffer);
627 if (buffer.len == 40)
628 ret = get_sha1_hex(buffer.buf, ref->old_sha1);
629 - else
629 + else if (!prefixcmp(buffer.buf, "ref: ")) {
630 + ref->symref = xstrdup(buffer.buf + 5);
631 + ret = 0;
632 + } else
633 ret = 1;
634 } else {
635 ret = error("Couldn't get %s for %s\n%s",
remote.c
+22 -1
@@ -706,13 +706,22 @@ struct ref *copy_ref_list(const struct ref *ref)
706 return ret;
707 }
708
709 +void free_ref(struct ref *ref)
710 +{
711 + if (!ref)
712 + return;
713 + free(ref->remote_status);
714 + free(ref->symref);
715 + free(ref);
716 +}
717 +
718 void free_refs(struct ref *ref)
719 {
720 struct ref *next;
721 while (ref) {
722 next = ref->next;
723 free(ref->peer_ref);
715 - free(ref);
724 + free_ref(ref);
725 ref = next;
726 }
727 }
@@ -1172,3 +1181,15 @@ int get_fetch_map(const struct ref *remote_refs,
1181
1182 return 0;
1183 }
1184 +
1185 +int resolve_remote_symref(struct ref *ref, struct ref *list)
1186 +{
1187 + if (!ref->symref)
1188 + return 0;
1189 + for (; list; list = list->next)
1190 + if (!strcmp(ref->symref, list->name)) {
1191 + hashcpy(ref->old_sha1, list->old_sha1);
1192 + return 0;
1193 + }
1194 + return 1;
1195 +}
remote.h
+2
@@ -62,6 +62,8 @@ int check_ref_type(const struct ref *ref, int flags);
62 */
63 void free_refs(struct ref *ref);
64
65 +int resolve_remote_symref(struct ref *ref, struct ref *list);
66 +
67 /*
68 * Removes and frees any duplicate refs in the map.
69 */
transport.c
+14
@@ -441,10 +441,14 @@ static struct ref *get_refs_via_curl(struct transport *transport)
441 struct ref *ref = NULL;
442 struct ref *last_ref = NULL;
443
444 + struct walker *walker;
445 +
446 if (!transport->data)
447 transport->data = get_http_walker(transport->url,
448 transport->remote);
449
450 + walker = transport->data;
451 +
452 refs_url = xmalloc(strlen(transport->url) + 11);
453 sprintf(refs_url, "%s/info/refs", transport->url);
454
@@ -500,6 +504,16 @@ static struct ref *get_refs_via_curl(struct transport *transport)
504
505 strbuf_release(&buffer);
506
507 + ref = alloc_ref(strlen("HEAD") + 1);
508 + strcpy(ref->name, "HEAD");
509 + if (!walker->fetch_ref(walker, ref) &&
510 + !resolve_remote_symref(ref, refs)) {
511 + ref->next = refs;
512 + refs = ref;
513 + } else {
514 + free(ref);
515 + }
516 +
517 return refs;
518 }
519