Merge branch 'db/learn-HEAD'

* db/learn-HEAD:
  Make ls-remote http://... list HEAD, like for git://...
  Make walker.fetch_ref() take a struct ref.
This commit is contained in:
Junio C Hamano 2008-05-08 20:06:23 -07:00
commit 31a3c6bb45
10 changed files with 79 additions and 29 deletions

View File

@ -635,6 +635,7 @@ struct ref {
struct ref *next; struct ref *next;
unsigned char old_sha1[20]; unsigned char old_sha1[20];
unsigned char new_sha1[20]; unsigned char new_sha1[20];
char *symref;
unsigned int force:1, unsigned int force:1,
merge:1, merge:1,
nonfastforward:1, nonfastforward:1,

View File

@ -1759,15 +1759,16 @@ static int one_local_ref(const char *refname, const unsigned char *sha1, int fla
static void one_remote_ref(char *refname) static void one_remote_ref(char *refname)
{ {
struct ref *ref; struct ref *ref;
unsigned char remote_sha1[20];
struct object *obj; struct object *obj;
int len = strlen(refname) + 1;
if (http_fetch_ref(remote->url, refname + 5 /* "refs/" */, ref = alloc_ref(strlen(refname) + 1);
remote_sha1) != 0) { strcpy(ref->name, refname);
if (http_fetch_ref(remote->url, ref) != 0) {
fprintf(stderr, fprintf(stderr,
"Unable to fetch ref %s from %s\n", "Unable to fetch ref %s from %s\n",
refname, remote->url); refname, remote->url);
free(ref);
return; return;
} }
@ -1775,18 +1776,15 @@ static void one_remote_ref(char *refname)
* Fetch a copy of the object if it doesn't exist locally - it * Fetch a copy of the object if it doesn't exist locally - it
* may be required for updating server info later. * may be required for updating server info later.
*/ */
if (remote->can_update_info_refs && !has_sha1_file(remote_sha1)) { if (remote->can_update_info_refs && !has_sha1_file(ref->old_sha1)) {
obj = lookup_unknown_object(remote_sha1); obj = lookup_unknown_object(ref->old_sha1);
if (obj) { if (obj) {
fprintf(stderr, " fetch %s for %s\n", fprintf(stderr, " fetch %s for %s\n",
sha1_to_hex(remote_sha1), refname); sha1_to_hex(ref->old_sha1), refname);
add_fetch_request(obj); add_fetch_request(obj);
} }
} }
ref = xcalloc(1, sizeof(*ref) + len);
hashcpy(ref->old_sha1, remote_sha1);
memcpy(ref->name, refname, len);
*remote_tail = ref; *remote_tail = ref;
remote_tail = &ref->next; remote_tail = &ref->next;
} }
@ -1891,33 +1889,37 @@ static void mark_edges_uninteresting(struct commit_list *list)
static void add_remote_info_ref(struct remote_ls_ctx *ls) static void add_remote_info_ref(struct remote_ls_ctx *ls)
{ {
struct strbuf *buf = (struct strbuf *)ls->userData; struct strbuf *buf = (struct strbuf *)ls->userData;
unsigned char remote_sha1[20];
struct object *o; struct object *o;
int len; int len;
char *ref_info; char *ref_info;
struct ref *ref;
if (http_fetch_ref(remote->url, ls->dentry_name + 5 /* "refs/" */, ref = alloc_ref(strlen(ls->dentry_name) + 1);
remote_sha1) != 0) { strcpy(ref->name, ls->dentry_name);
if (http_fetch_ref(remote->url, ref) != 0) {
fprintf(stderr, fprintf(stderr,
"Unable to fetch ref %s from %s\n", "Unable to fetch ref %s from %s\n",
ls->dentry_name, remote->url); ls->dentry_name, remote->url);
aborted = 1; aborted = 1;
free(ref);
return; return;
} }
o = parse_object(remote_sha1); o = parse_object(ref->old_sha1);
if (!o) { if (!o) {
fprintf(stderr, fprintf(stderr,
"Unable to parse object %s for remote ref %s\n", "Unable to parse object %s for remote ref %s\n",
sha1_to_hex(remote_sha1), ls->dentry_name); sha1_to_hex(ref->old_sha1), ls->dentry_name);
aborted = 1; aborted = 1;
free(ref);
return; return;
} }
len = strlen(ls->dentry_name) + 42; len = strlen(ls->dentry_name) + 42;
ref_info = xcalloc(len + 1, 1); ref_info = xcalloc(len + 1, 1);
sprintf(ref_info, "%s %s\n", sprintf(ref_info, "%s %s\n",
sha1_to_hex(remote_sha1), ls->dentry_name); sha1_to_hex(ref->old_sha1), ls->dentry_name);
fwrite_buffer(ref_info, 1, len, buf); fwrite_buffer(ref_info, 1, len, buf);
free(ref_info); free(ref_info);
@ -1932,6 +1934,7 @@ static void add_remote_info_ref(struct remote_ls_ctx *ls)
free(ref_info); free(ref_info);
} }
} }
free(ref);
} }
static void update_remote_info_refs(struct remote_lock *lock) static void update_remote_info_refs(struct remote_lock *lock)

View File

@ -888,10 +888,10 @@ static int fetch(struct walker *walker, unsigned char *sha1)
data->alt->base); data->alt->base);
} }
static int fetch_ref(struct walker *walker, char *ref, unsigned char *sha1) static int fetch_ref(struct walker *walker, struct ref *ref)
{ {
struct walker_data *data = walker->data; struct walker_data *data = walker->data;
return http_fetch_ref(data->alt->base, ref, sha1); return http_fetch_ref(data->alt->base, ref);
} }
static void cleanup(struct walker *walker) static void cleanup(struct walker *walker)

18
http.c
View File

@ -589,8 +589,9 @@ static char *quote_ref_url(const char *base, const char *ref)
len += 2; /* extra two hex plus replacement % */ len += 2; /* extra two hex plus replacement % */
qref = xmalloc(len); qref = xmalloc(len);
memcpy(qref, base, baselen); memcpy(qref, base, baselen);
memcpy(qref + baselen, "/refs/", 6); dp = qref + baselen;
for (cp = ref, dp = qref + baselen + 6; (ch = *cp) != 0; cp++) { *(dp++) = '/';
for (cp = ref; (ch = *cp) != 0; cp++) {
if (needs_quote(ch)) { if (needs_quote(ch)) {
*dp++ = '%'; *dp++ = '%';
*dp++ = hex((ch >> 4) & 0xF); *dp++ = hex((ch >> 4) & 0xF);
@ -604,7 +605,7 @@ static char *quote_ref_url(const char *base, const char *ref)
return qref; 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; char *url;
struct strbuf buffer = STRBUF_INIT; 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; struct slot_results results;
int ret; int ret;
url = quote_ref_url(base, ref); url = quote_ref_url(base, ref->name);
slot = get_active_slot(); slot = get_active_slot();
slot->results = &results; slot->results = &results;
curl_easy_setopt(slot->curl, CURLOPT_FILE, &buffer); curl_easy_setopt(slot->curl, CURLOPT_FILE, &buffer);
@ -624,12 +625,15 @@ int http_fetch_ref(const char *base, const char *ref, unsigned char *sha1)
if (results.curl_result == CURLE_OK) { if (results.curl_result == CURLE_OK) {
strbuf_rtrim(&buffer); strbuf_rtrim(&buffer);
if (buffer.len == 40) if (buffer.len == 40)
ret = get_sha1_hex(buffer.buf, sha1); 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; ret = 1;
} else { } else {
ret = error("Couldn't get %s for %s\n%s", ret = error("Couldn't get %s for %s\n%s",
url, ref, curl_errorstr); url, ref->name, curl_errorstr);
} }
} else { } else {
ret = error("Unable to start request"); ret = error("Unable to start request");

2
http.h
View File

@ -105,6 +105,6 @@ static inline int missing__target(int code, int result)
#define missing_target(a) missing__target((a)->http_code, (a)->curl_result) #define missing_target(a) missing__target((a)->http_code, (a)->curl_result)
extern int http_fetch_ref(const char *base, const char *ref, unsigned char *sha1); extern int http_fetch_ref(const char *base, struct ref *ref);
#endif /* HTTP_H */ #endif /* HTTP_H */

View File

@ -711,13 +711,22 @@ struct ref *copy_ref_list(const struct ref *ref)
return ret; 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) void free_refs(struct ref *ref)
{ {
struct ref *next; struct ref *next;
while (ref) { while (ref) {
next = ref->next; next = ref->next;
free(ref->peer_ref); free(ref->peer_ref);
free(ref); free_ref(ref);
ref = next; ref = next;
} }
} }
@ -1177,3 +1186,15 @@ int get_fetch_map(const struct ref *remote_refs,
return 0; 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;
}

View File

@ -63,6 +63,8 @@ int check_ref_type(const struct ref *ref, int flags);
*/ */
void free_refs(struct ref *ref); 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. * Removes and frees any duplicate refs in the map.
*/ */

View File

@ -441,10 +441,14 @@ static struct ref *get_refs_via_curl(struct transport *transport)
struct ref *ref = NULL; struct ref *ref = NULL;
struct ref *last_ref = NULL; struct ref *last_ref = NULL;
struct walker *walker;
if (!transport->data) if (!transport->data)
transport->data = get_http_walker(transport->url, transport->data = get_http_walker(transport->url,
transport->remote); transport->remote);
walker = transport->data;
refs_url = xmalloc(strlen(transport->url) + 11); refs_url = xmalloc(strlen(transport->url) + 11);
sprintf(refs_url, "%s/info/refs", transport->url); 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); 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; return refs;
} }

View File

@ -190,9 +190,14 @@ static int interpret_target(struct walker *walker, char *target, unsigned char *
if (!get_sha1_hex(target, sha1)) if (!get_sha1_hex(target, sha1))
return 0; return 0;
if (!check_ref_format(target)) { if (!check_ref_format(target)) {
if (!walker->fetch_ref(walker, target, sha1)) { struct ref *ref = alloc_ref(strlen(target));
strcpy(ref->name, target);
if (!walker->fetch_ref(walker, ref)) {
hashcpy(sha1, ref->old_sha1);
free(ref);
return 0; return 0;
} }
free(ref);
} }
return -1; return -1;
} }

View File

@ -5,7 +5,7 @@
struct walker { struct walker {
void *data; void *data;
int (*fetch_ref)(struct walker *, char *ref, unsigned char *sha1); int (*fetch_ref)(struct walker *, struct ref *ref);
void (*prefetch)(struct walker *, unsigned char *sha1); void (*prefetch)(struct walker *, unsigned char *sha1);
int (*fetch)(struct walker *, unsigned char *sha1); int (*fetch)(struct walker *, unsigned char *sha1);
void (*cleanup)(struct walker *); void (*cleanup)(struct walker *);