author | Junio C Hamano <gitster@pobox.com> | |
Fri, 9 May 2008 03:06:23 +0000 (20:06 -0700) | ||
committer | Junio C Hamano <gitster@pobox.com> | |
Fri, 9 May 2008 03:06:23 +0000 (20:06 -0700) |
* db/learn-HEAD:
Make ls-remote http://... list HEAD, like for git://...
Make walker.fetch_ref() take a struct ref.
Make ls-remote http://... list HEAD, like for git://...
Make walker.fetch_ref() take a struct ref.
cache.h | patch | blob | history | |
http-push.c | patch | blob | history | |
http-walker.c | patch | blob | history | |
http.c | patch | blob | history | |
http.h | patch | blob | history | |
remote.c | patch | blob | history | |
remote.h | patch | blob | history | |
transport.c | patch | blob | history | |
walker.c | patch | blob | history | |
walker.h | patch | blob | history |
index d5d5dad1463e2251dc84cf0a85095a7e3e0eaeae..7fb8f3359dddbb8f93aa827947c3e5d9de04f639 100644 (file)
--- a/cache.h
+++ b/cache.h
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-push.c b/http-push.c
index 5b230380ccd33d8b04f8dfce24050237ae9206ad..939a76460232f9097b20e43d71b35efbdad97b52 100644 (file)
--- a/http-push.c
+++ b/http-push.c
@@ -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)
{
struct ref *ref;
- unsigned char remote_sha1[20];
struct object *obj;
- int len = strlen(refname) + 1;
- if (http_fetch_ref(remote->url, refname + 5 /* "refs/" */,
- remote_sha1) != 0) {
+ ref = alloc_ref(strlen(refname) + 1);
+ strcpy(ref->name, refname);
+
+ if (http_fetch_ref(remote->url, ref) != 0) {
fprintf(stderr,
"Unable to fetch ref %s from %s\n",
refname, remote->url);
+ free(ref);
return;
}
* Fetch a copy of the object if it doesn't exist locally - it
* may be required for updating server info later.
*/
- if (remote->can_update_info_refs && !has_sha1_file(remote_sha1)) {
- obj = lookup_unknown_object(remote_sha1);
+ if (remote->can_update_info_refs && !has_sha1_file(ref->old_sha1)) {
+ obj = lookup_unknown_object(ref->old_sha1);
if (obj) {
fprintf(stderr, " fetch %s for %s\n",
- sha1_to_hex(remote_sha1), refname);
+ sha1_to_hex(ref->old_sha1), refname);
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->next;
}
static void add_remote_info_ref(struct remote_ls_ctx *ls)
{
struct strbuf *buf = (struct strbuf *)ls->userData;
- unsigned char remote_sha1[20];
struct object *o;
int len;
char *ref_info;
+ struct ref *ref;
+
+ ref = alloc_ref(strlen(ls->dentry_name) + 1);
+ strcpy(ref->name, ls->dentry_name);
- if (http_fetch_ref(remote->url, ls->dentry_name + 5 /* "refs/" */,
- remote_sha1) != 0) {
+ if (http_fetch_ref(remote->url, ref) != 0) {
fprintf(stderr,
"Unable to fetch ref %s from %s\n",
ls->dentry_name, remote->url);
aborted = 1;
+ free(ref);
return;
}
- o = parse_object(remote_sha1);
+ o = parse_object(ref->old_sha1);
if (!o) {
fprintf(stderr,
"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;
+ free(ref);
return;
}
len = strlen(ls->dentry_name) + 42;
ref_info = xcalloc(len + 1, 1);
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);
free(ref_info);
free(ref_info);
}
}
+ free(ref);
}
static void update_remote_info_refs(struct remote_lock *lock)
diff --git a/http-walker.c b/http-walker.c
index 7bda34d91498c3959569327ea2132851230999e7..99f397e32b673e289c2f9d298b1287a97cb7a49e 100644 (file)
--- a/http-walker.c
+++ b/http-walker.c
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;
- return http_fetch_ref(data->alt->base, ref, sha1);
+ return http_fetch_ref(data->alt->base, ref);
}
static void cleanup(struct walker *walker)
index 256a5f15f40a8d9389560e1fb08e34a56e9f7140..acf746a12da0f0b5e3fe3f097a6626e17da8852c 100644 (file)
--- a/http.c
+++ b/http.c
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);
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;
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);
if (results.curl_result == CURLE_OK) {
strbuf_rtrim(&buffer);
if (buffer.len == 40)
- ret = get_sha1_hex(buffer.buf, sha1);
- else
+ ret = get_sha1_hex(buffer.buf, ref->old_sha1);
+ 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",
- url, ref, curl_errorstr);
+ url, ref->name, curl_errorstr);
}
} else {
ret = error("Unable to start request");
index 04169d5f9c8fa4cb82ad720b9e6d371f02be83d3..a04fc6a9277945a7084e718753c133ed47d13691 100644 (file)
--- a/http.h
+++ b/http.h
#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 */
diff --git a/remote.c b/remote.c
index 870d224a3931bf0468c0b74334c0fb49a06ad731..6b480cbb9808d9e2b77f2a88f0324701e02a8a75 100644 (file)
--- a/remote.c
+++ b/remote.c
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;
}
}
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 6878c52ce0e3fa57693e919a9cdb66748bb6e6e3..75d006b6deb2ded726df2c1749aa63dec69e34d2 100644 (file)
--- a/remote.h
+++ b/remote.h
*/
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 393e0e8fe233ca51dc4c5db94c55e81ee53baa52..b012a283386de601a7f5df15b11b659c5297f21d 100644 (file)
--- a/transport.c
+++ b/transport.c
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);
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;
}
diff --git a/walker.c b/walker.c
index c10eca88261eed6b0e5c3fc2fdc19b8332c4ac6b..fa96a7c7d293ee43a86317c8407d4e960311d59e 100644 (file)
--- a/walker.c
+++ b/walker.c
@@ -190,9 +190,14 @@ static int interpret_target(struct walker *walker, char *target, unsigned char *
if (!get_sha1_hex(target, sha1))
return 0;
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;
}
+ free(ref);
}
return -1;
}
diff --git a/walker.h b/walker.h
index e1d40deaffa5965b1edd381a610ab225e027e3b2..8a149e11084eeec4501b5b2c5d22e5266f4852e7 100644 (file)
--- a/walker.h
+++ b/walker.h
struct walker {
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);
int (*fetch)(struct walker *, unsigned char *sha1);
void (*cleanup)(struct walker *);