{"thread":{"id":"13272","subject":"[PATCH 1/2] Make walker.fetch_ref() take a struct ref.","startedAt":"2008-04-26T19:53:09Z","lastAt":"2008-04-26T19:53:09Z","messageCount":1,"participants":["Daniel Barkalow"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"75234","messageId":"alpine.LNX.1.00.0804261547200.19665@iabervon.org","threadId":"13272","inReplyTo":null,"subject":"[PATCH 1/2] Make walker.fetch_ref() take a struct ref.","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2008-04-26T19:53:09Z","receivedAt":"2008-04-26T19:53:09Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"This simplifies a few things, makes a few things slightly more\ncomplicated, but, more importantly, allows that, when struct ref can\nrepresent a symref, http_fetch_ref() can return one.\n\nIncidentally makes the string that http_fetch_ref() gets include \"refs/\"\n(if appropriate), because that's how the name field of struct ref works. \nAs far as I can tell, the usage in walker:interpret_target() wouldn't have \nworked previously, if it ever would have been used, which it wouldn't \n(since the fetch process uses the hash instead of the name of the ref \nthere).\n\nSigned-off-by: Daniel Barkalow <barkalow@iabervon.org>\n---\nI'm fairly sure I got the http-push changes here right, but I don't have \ntesting infrastructure for it set up, so I'd appreciate testing from \nsomebody who does.\n\n http-push.c   |   35 +++++++++++++++++++----------------\n http-walker.c |    4 ++--\n http.c        |   13 +++++++------\n http.h        |    2 +-\n walker.c      |    7 ++++++-\n walker.h      |    2 +-\n 6 files changed, 36 insertions(+), 27 deletions(-)\n\ndiff --git a/http-push.c b/http-push.c\nindex 5b23038..939a764 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -1759,15 +1759,16 @@ static int one_local_ref(const char *refname, const unsigned char *sha1, int fla\n static void one_remote_ref(char *refname)\n {\n \tstruct ref *ref;\n-\tunsigned char remote_sha1[20];\n \tstruct object *obj;\n-\tint len = strlen(refname) + 1;\n \n-\tif (http_fetch_ref(remote->url, refname + 5 /* \"refs/\" */,\n-\t\t\t   remote_sha1) != 0) {\n+\tref = alloc_ref(strlen(refname) + 1);\n+\tstrcpy(ref->name, refname);\n+\n+\tif (http_fetch_ref(remote->url, ref) != 0) {\n \t\tfprintf(stderr,\n \t\t\t\"Unable to fetch ref %s from %s\\n\",\n \t\t\trefname, remote->url);\n+\t\tfree(ref);\n \t\treturn;\n \t}\n \n@@ -1775,18 +1776,15 @@ static void one_remote_ref(char *refname)\n \t * Fetch a copy of the object if it doesn't exist locally - it\n \t * may be required for updating server info later.\n \t */\n-\tif (remote->can_update_info_refs && !has_sha1_file(remote_sha1)) {\n-\t\tobj = lookup_unknown_object(remote_sha1);\n+\tif (remote->can_update_info_refs && !has_sha1_file(ref->old_sha1)) {\n+\t\tobj = lookup_unknown_object(ref->old_sha1);\n \t\tif (obj) {\n \t\t\tfprintf(stderr,\t\"  fetch %s for %s\\n\",\n-\t\t\t\tsha1_to_hex(remote_sha1), refname);\n+\t\t\t\tsha1_to_hex(ref->old_sha1), refname);\n \t\t\tadd_fetch_request(obj);\n \t\t}\n \t}\n \n-\tref = xcalloc(1, sizeof(*ref) + len);\n-\thashcpy(ref->old_sha1, remote_sha1);\n-\tmemcpy(ref->name, refname, len);\n \t*remote_tail = ref;\n \tremote_tail = &ref->next;\n }\n@@ -1891,33 +1889,37 @@ static void mark_edges_uninteresting(struct commit_list *list)\n static void add_remote_info_ref(struct remote_ls_ctx *ls)\n {\n \tstruct strbuf *buf = (struct strbuf *)ls->userData;\n-\tunsigned char remote_sha1[20];\n \tstruct object *o;\n \tint len;\n \tchar *ref_info;\n+\tstruct ref *ref;\n+\n+\tref = alloc_ref(strlen(ls->dentry_name) + 1);\n+\tstrcpy(ref->name, ls->dentry_name);\n \n-\tif (http_fetch_ref(remote->url, ls->dentry_name + 5 /* \"refs/\" */,\n-\t\t\t   remote_sha1) != 0) {\n+\tif (http_fetch_ref(remote->url, ref) != 0) {\n \t\tfprintf(stderr,\n \t\t\t\"Unable to fetch ref %s from %s\\n\",\n \t\t\tls->dentry_name, remote->url);\n \t\taborted = 1;\n+\t\tfree(ref);\n \t\treturn;\n \t}\n \n-\to = parse_object(remote_sha1);\n+\to = parse_object(ref->old_sha1);\n \tif (!o) {\n \t\tfprintf(stderr,\n \t\t\t\"Unable to parse object %s for remote ref %s\\n\",\n-\t\t\tsha1_to_hex(remote_sha1), ls->dentry_name);\n+\t\t\tsha1_to_hex(ref->old_sha1), ls->dentry_name);\n \t\taborted = 1;\n+\t\tfree(ref);\n \t\treturn;\n \t}\n \n \tlen = strlen(ls->dentry_name) + 42;\n \tref_info = xcalloc(len + 1, 1);\n \tsprintf(ref_info, \"%s\t%s\\n\",\n-\t\tsha1_to_hex(remote_sha1), ls->dentry_name);\n+\t\tsha1_to_hex(ref->old_sha1), ls->dentry_name);\n \tfwrite_buffer(ref_info, 1, len, buf);\n \tfree(ref_info);\n \n@@ -1932,6 +1934,7 @@ static void add_remote_info_ref(struct remote_ls_ctx *ls)\n \t\t\tfree(ref_info);\n \t\t}\n \t}\n+\tfree(ref);\n }\n \n static void update_remote_info_refs(struct remote_lock *lock)\ndiff --git a/http-walker.c b/http-walker.c\nindex 7bda34d..99f397e 100644\n--- a/http-walker.c\n+++ b/http-walker.c\n@@ -888,10 +888,10 @@ static int fetch(struct walker *walker, unsigned char *sha1)\n \t\t     data->alt->base);\n }\n \n-static int fetch_ref(struct walker *walker, char *ref, unsigned char *sha1)\n+static int fetch_ref(struct walker *walker, struct ref *ref)\n {\n \tstruct walker_data *data = walker->data;\n-\treturn http_fetch_ref(data->alt->base, ref, sha1);\n+\treturn http_fetch_ref(data->alt->base, ref);\n }\n \n static void cleanup(struct walker *walker)\ndiff --git a/http.c b/http.c\nindex 256a5f1..c8df13b 100644\n--- a/http.c\n+++ b/http.c\n@@ -589,8 +589,9 @@ static char *quote_ref_url(const char *base, const char *ref)\n \t\t\tlen += 2; /* extra two hex plus replacement % */\n \tqref = xmalloc(len);\n \tmemcpy(qref, base, baselen);\n-\tmemcpy(qref + baselen, \"/refs/\", 6);\n-\tfor (cp = ref, dp = qref + baselen + 6; (ch = *cp) != 0; cp++) {\n+\tdp = qref + baselen;\n+\t*(dp++) = '/';\n+\tfor (cp = ref; (ch = *cp) != 0; cp++) {\n \t\tif (needs_quote(ch)) {\n \t\t\t*dp++ = '%';\n \t\t\t*dp++ = hex((ch >> 4) & 0xF);\n@@ -604,7 +605,7 @@ static char *quote_ref_url(const char *base, const char *ref)\n \treturn qref;\n }\n \n-int http_fetch_ref(const char *base, const char *ref, unsigned char *sha1)\n+int http_fetch_ref(const char *base, struct ref *ref)\n {\n \tchar *url;\n \tstruct strbuf buffer = STRBUF_INIT;\n@@ -612,7 +613,7 @@ int http_fetch_ref(const char *base, const char *ref, unsigned char *sha1)\n \tstruct slot_results results;\n \tint ret;\n \n-\turl = quote_ref_url(base, ref);\n+\turl = quote_ref_url(base, ref->name);\n \tslot = get_active_slot();\n \tslot->results = &results;\n \tcurl_easy_setopt(slot->curl, CURLOPT_FILE, &buffer);\n@@ -624,12 +625,12 @@ int http_fetch_ref(const char *base, const char *ref, unsigned char *sha1)\n \t\tif (results.curl_result == CURLE_OK) {\n \t\t\tstrbuf_rtrim(&buffer);\n \t\t\tif (buffer.len == 40)\n-\t\t\t\tret = get_sha1_hex(buffer.buf, sha1);\n+\t\t\t\tret = get_sha1_hex(buffer.buf, ref->old_sha1);\n \t\t\telse\n \t\t\t\tret = 1;\n \t\t} else {\n \t\t\tret = error(\"Couldn't get %s for %s\\n%s\",\n-\t\t\t\t    url, ref, curl_errorstr);\n+\t\t\t\t    url, ref->name, curl_errorstr);\n \t\t}\n \t} else {\n \t\tret = error(\"Unable to start request\");\ndiff --git a/http.h b/http.h\nindex 04169d5..a04fc6a 100644\n--- a/http.h\n+++ b/http.h\n@@ -105,6 +105,6 @@ static inline int missing__target(int code, int result)\n \n #define missing_target(a) missing__target((a)->http_code, (a)->curl_result)\n \n-extern int http_fetch_ref(const char *base, const char *ref, unsigned char *sha1);\n+extern int http_fetch_ref(const char *base, struct ref *ref);\n \n #endif /* HTTP_H */\ndiff --git a/walker.c b/walker.c\nindex c10eca8..fa96a7c 100644\n--- a/walker.c\n+++ b/walker.c\n@@ -190,9 +190,14 @@ static int interpret_target(struct walker *walker, char *target, unsigned char *\n \tif (!get_sha1_hex(target, sha1))\n \t\treturn 0;\n \tif (!check_ref_format(target)) {\n-\t\tif (!walker->fetch_ref(walker, target, sha1)) {\n+\t\tstruct ref *ref = alloc_ref(strlen(target));\n+\t\tstrcpy(ref->name, target);\n+\t\tif (!walker->fetch_ref(walker, ref)) {\n+\t\t\thashcpy(sha1, ref->old_sha1);\n+\t\t\tfree(ref);\n \t\t\treturn 0;\n \t\t}\n+\t\tfree(ref);\n \t}\n \treturn -1;\n }\ndiff --git a/walker.h b/walker.h\nindex e1d40de..8a149e1 100644\n--- a/walker.h\n+++ b/walker.h\n@@ -5,7 +5,7 @@\n \n struct walker {\n \tvoid *data;\n-\tint (*fetch_ref)(struct walker *, char *ref, unsigned char *sha1);\n+\tint (*fetch_ref)(struct walker *, struct ref *ref);\n \tvoid (*prefetch)(struct walker *, unsigned char *sha1);\n \tint (*fetch)(struct walker *, unsigned char *sha1);\n \tvoid (*cleanup)(struct walker *);\n-- \n1.5.4.3.610.gea6cd\n"}]}