{"thread":{"id":"22645","subject":"[PATCH 3/4] for-each-ref --format='%(symref) %(symref:short)'","startedAt":"2010-02-13T20:30:29Z","lastAt":"2010-02-15T08:39:24Z","messageCount":8,"participants":["Junio C Hamano","Jeff King"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"134463","messageId":"1266093033-9526-1-git-send-email-gitster@pobox.com","threadId":"22645","inReplyTo":"20100213085132.GA13181@coredump.intra.peff.net","subject":"[PATCH 0/4] for-each-ref --format='%(symref) %(symref:short) %(flag)'","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-02-13T20:30:29Z","receivedAt":"2010-02-13T20:30:29Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Here is my attempt to summarize the discussion so far.\n\nJunio C Hamano (4):\n  builtin-for-each-ref.c: comment fixes\n  builtin-for-each-ref.c: check if we need to peel onion while parsing\n    the format\n  for-each-ref --format='%(symref) %(symref:short)'\n  for-each-ref --format='%(flag)'\n\n builtin-for-each-ref.c |   77 ++++++++++++++++++++++++++++++++++++-----------\n 1 files changed, 59 insertions(+), 18 deletions(-)\n"},{"id":"134462","messageId":"1266093033-9526-2-git-send-email-gitster@pobox.com","threadId":"22645","inReplyTo":"1266093033-9526-1-git-send-email-gitster@pobox.com","subject":"[PATCH 1/4] builtin-for-each-ref.c: comment fixes","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-02-13T20:30:30Z","receivedAt":"2010-02-13T20:30:30Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"The primary purpose of this is to get rid of stale comments that lamented\nthe lack of callback parameter from for_each_ref(), which we have already\nfixed.  While at it, adjust the multi-line comment style as well.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n builtin-for-each-ref.c |   26 ++++++++++++++++----------\n 1 files changed, 16 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin-for-each-ref.c b/builtin-for-each-ref.c\nindex a5a83f1..3698e82 100644\n--- a/builtin-for-each-ref.c\n+++ b/builtin-for-each-ref.c\n@@ -143,7 +143,8 @@ static const char *find_next(const char *cp)\n {\n \twhile (*cp) {\n \t\tif (*cp == '%') {\n-\t\t\t/* %( is the start of an atom;\n+\t\t\t/*\n+\t\t\t * %( is the start of an atom;\n \t\t\t * %% is a quoted per-cent.\n \t\t\t */\n \t\t\tif (cp[1] == '(')\n@@ -420,7 +421,8 @@ static void grab_person(const char *who, struct atom_value *val, int deref, stru\n \t\t\tgrab_date(wholine, v, name);\n \t}\n \n-\t/* For a tag or a commit object, if \"creator\" or \"creatordate\" is\n+\t/*\n+\t * For a tag or a commit object, if \"creator\" or \"creatordate\" is\n \t * requested, do something special.\n \t */\n \tif (strcmp(who, \"tagger\") && strcmp(who, \"committer\"))\n@@ -502,7 +504,8 @@ static void grab_sub_body_contents(struct atom_value *val, int deref, struct obj\n \t}\n }\n \n-/* We want to have empty print-string for field requests\n+/*\n+ * We want to have empty print-string for field requests\n  * that do not apply (e.g. \"authordate\" for a tag object)\n  */\n static void fill_missing_values(struct atom_value *val)\n@@ -633,18 +636,21 @@ static void populate_value(struct refinfo *ref)\n \tif (!eaten)\n \t\tfree(buf);\n \n-\t/* If there is no atom that wants to know about tagged\n+\t/*\n+\t * If there is no atom that wants to know about tagged\n \t * object, we are done.\n \t */\n \tif (!need_tagged || (obj->type != OBJ_TAG))\n \t\treturn;\n \n-\t/* If it is a tag object, see if we use a value that derefs\n+\t/*\n+\t * If it is a tag object, see if we use a value that derefs\n \t * the object, and if we do grab the object it refers to.\n \t */\n \ttagged = ((struct tag *)obj)->tagged->sha1;\n \n-\t/* NEEDSWORK: This derefs tag only once, which\n+\t/*\n+\t * NEEDSWORK: This derefs tag only once, which\n \t * is good to deal with chains of trust, but\n \t * is not consistent with what deref_tag() does\n \t * which peels the onion to the core.\n@@ -681,9 +687,8 @@ struct grab_ref_cbdata {\n };\n \n /*\n- * A call-back given to for_each_ref().  It is unfortunate that we\n- * need to use global variables to pass extra information to this\n- * function.\n+ * A call-back given to for_each_ref().  Filter refs and keep them for\n+ * later object processing.\n  */\n static int grab_single_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)\n {\n@@ -711,7 +716,8 @@ static int grab_single_ref(const char *refname, const unsigned char *sha1, int f\n \t\t\treturn 0;\n \t}\n \n-\t/* We do not open the object yet; sort may only need refname\n+\t/*\n+\t * We do not open the object yet; sort may only need refname\n \t * to do its job and the resulting list may yet to be pruned\n \t * by maxcount logic.\n \t */\n-- \n1.7.0.169.g57c99\n"},{"id":"134461","messageId":"1266093033-9526-3-git-send-email-gitster@pobox.com","threadId":"22645","inReplyTo":"1266093033-9526-1-git-send-email-gitster@pobox.com","subject":"[PATCH 2/4] builtin-for-each-ref.c: check if we need to peel onion while parsing the format","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-02-13T20:30:31Z","receivedAt":"2010-02-13T20:30:31Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Instead of iterating over the parsed atoms that are used in the output\nformat after all the parsing is done, check it while parsing the\nformat string.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n builtin-for-each-ref.c |    9 ++-------\n 1 files changed, 2 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin-for-each-ref.c b/builtin-for-each-ref.c\nindex 3698e82..d68977e 100644\n--- a/builtin-for-each-ref.c\n+++ b/builtin-for-each-ref.c\n@@ -133,6 +133,8 @@ static int parse_atom(const char *atom, const char *ep)\n \t\t\t\t  (sizeof(*used_atom_type) * used_atom_cnt));\n \tused_atom[at] = xmemdupz(atom, ep - atom);\n \tused_atom_type[at] = valid_atom[i].cmp_type;\n+\tif (*atom == '*')\n+\t\tneed_tagged = 1;\n \treturn at;\n }\n \n@@ -944,13 +946,6 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)\n \trefs = cbdata.grab_array;\n \tnum_refs = cbdata.grab_cnt;\n \n-\tfor (i = 0; i < used_atom_cnt; i++) {\n-\t\tif (used_atom[i][0] == '*') {\n-\t\t\tneed_tagged = 1;\n-\t\t\tbreak;\n-\t\t}\n-\t}\n-\n \tsort_refs(sort, refs, num_refs);\n \n \tif (!maxcount || num_refs < maxcount)\n-- \n1.7.0.169.g57c99\n"},{"id":"134459","messageId":"1266093033-9526-4-git-send-email-gitster@pobox.com","threadId":"22645","inReplyTo":"1266093033-9526-1-git-send-email-gitster@pobox.com","subject":"[PATCH 3/4] for-each-ref --format='%(symref) %(symref:short)'","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-02-13T20:30:32Z","receivedAt":"2010-02-13T20:30:32Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"New %(symref) output atom expands to the name of the ref a symbolic ref\npoints at, or an empty string if the ref being shown is not a symref.\n\nThis may help scripted Porcelain writers.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n builtin-for-each-ref.c |   20 +++++++++++++++++++-\n 1 files changed, 19 insertions(+), 1 deletions(-)\n\ndiff --git a/builtin-for-each-ref.c b/builtin-for-each-ref.c\nindex d68977e..b9b03e1 100644\n--- a/builtin-for-each-ref.c\n+++ b/builtin-for-each-ref.c\n@@ -33,6 +33,8 @@ struct ref_sort {\n struct refinfo {\n \tchar *refname;\n \tunsigned char objectname[20];\n+\tint flag;\n+\tconst char *symref;\n \tstruct atom_value *value;\n };\n \n@@ -68,6 +70,7 @@ static struct {\n \t{ \"body\" },\n \t{ \"contents\" },\n \t{ \"upstream\" },\n+\t{ \"symref\" },\n };\n \n /*\n@@ -82,7 +85,7 @@ static struct {\n  */\n static const char **used_atom;\n static cmp_type *used_atom_type;\n-static int used_atom_cnt, sort_atom_limit, need_tagged;\n+static int used_atom_cnt, sort_atom_limit, need_tagged, need_symref;\n \n /*\n  * Used to parse format string and sort specifiers\n@@ -135,6 +138,8 @@ static int parse_atom(const char *atom, const char *ep)\n \tused_atom_type[at] = valid_atom[i].cmp_type;\n \tif (*atom == '*')\n \t\tneed_tagged = 1;\n+\tif (!strcmp(used_atom[at], \"symref\"))\n+\t\tneed_symref = 1;\n \treturn at;\n }\n \n@@ -566,6 +571,16 @@ static void populate_value(struct refinfo *ref)\n \n \tref->value = xcalloc(sizeof(struct atom_value), used_atom_cnt);\n \n+\tif (need_symref && (ref->flag & REF_ISSYMREF) && !ref->symref) {\n+\t\tunsigned char unused1[20];\n+\t\tconst char *symref;\n+\t\tsymref = resolve_ref(ref->refname, unused1, 1, NULL);\n+\t\tif (symref)\n+\t\t\tref->symref = xstrdup(symref);\n+\t\telse\n+\t\t\tref->symref = \"\";\n+\t}\n+\n \t/* Fill in specials first */\n \tfor (i = 0; i < used_atom_cnt; i++) {\n \t\tconst char *name = used_atom[i];\n@@ -581,6 +596,8 @@ static void populate_value(struct refinfo *ref)\n \n \t\tif (!prefixcmp(name, \"refname\"))\n \t\t\trefname = ref->refname;\n+\t\telse if (!prefixcmp(name, \"symref\"))\n+\t\t\trefname = ref->symref ? ref->symref : \"\";\n \t\telse if (!prefixcmp(name, \"upstream\")) {\n \t\t\tstruct branch *branch;\n \t\t\t/* only local branches may have an upstream */\n@@ -726,6 +743,7 @@ static int grab_single_ref(const char *refname, const unsigned char *sha1, int f\n \tref = xcalloc(1, sizeof(*ref));\n \tref->refname = xstrdup(refname);\n \thashcpy(ref->objectname, sha1);\n+\tref->flag = flag;\n \n \tcnt = cb->grab_cnt;\n \tcb->grab_array = xrealloc(cb->grab_array,\n-- \n1.7.0.169.g57c99\n"},{"id":"134460","messageId":"1266093033-9526-5-git-send-email-gitster@pobox.com","threadId":"22645","inReplyTo":"1266093033-9526-1-git-send-email-gitster@pobox.com","subject":"[PATCH 4/4] for-each-ref --format='%(flag)'","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-02-13T20:30:33Z","receivedAt":"2010-02-13T20:30:33Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"This expands to \"symref\" or \"packed\" or an empty string, exposing the\ninternal \"flag\" the for_each_ref() callback functions are called with.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n builtin-for-each-ref.c |   22 ++++++++++++++++++++++\n 1 files changed, 22 insertions(+), 0 deletions(-)\n\ndiff --git a/builtin-for-each-ref.c b/builtin-for-each-ref.c\nindex b9b03e1..62be1bb 100644\n--- a/builtin-for-each-ref.c\n+++ b/builtin-for-each-ref.c\n@@ -71,6 +71,7 @@ static struct {\n \t{ \"contents\" },\n \t{ \"upstream\" },\n \t{ \"symref\" },\n+\t{ \"flag\" },\n };\n \n /*\n@@ -558,6 +559,13 @@ static void grab_values(struct atom_value *val, int deref, struct object *obj, v\n \t}\n }\n \n+static inline char *copy_advance(char *dst, const char *src)\n+{\n+\twhile (*src)\n+\t\t*dst++ = *src++;\n+\treturn dst;\n+}\n+\n /*\n  * Parse the object referred by ref, and grab needed value.\n  */\n@@ -610,6 +618,20 @@ static void populate_value(struct refinfo *ref)\n \t\t\t\tcontinue;\n \t\t\trefname = branch->merge[0]->dst;\n \t\t}\n+\t\telse if (!strcmp(name, \"flag\")) {\n+\t\t\tchar buf[256], *cp = buf;\n+\t\t\tif (ref->flag & REF_ISSYMREF)\n+\t\t\t\tcp = copy_advance(cp, \",symref\");\n+\t\t\tif (ref->flag & REF_ISPACKED)\n+\t\t\t\tcp = copy_advance(cp, \",packed\");\n+\t\t\tif (cp == buf)\n+\t\t\t\tv->s = \"\";\n+\t\t\telse {\n+\t\t\t\t*cp = '\\0';\n+\t\t\t\tv->s = xstrdup(buf + 1);\n+\t\t\t}\n+\t\t\tcontinue;\n+\t\t}\n \t\telse\n \t\t\tcontinue;\n \n-- \n1.7.0.169.g57c99\n"},{"id":"134519","messageId":"20100214063243.GA20630@coredump.intra.peff.net","threadId":"22645","inReplyTo":"1266093033-9526-4-git-send-email-gitster@pobox.com","subject":"Re: [PATCH 3/4] for-each-ref --format='%(symref) %(symref:short)'","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-02-14T06:32:43Z","receivedAt":"2010-02-14T06:32:43Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Feb 13, 2010 at 12:30:32PM -0800, Junio C Hamano wrote:\n\n> New %(symref) output atom expands to the name of the ref a symbolic ref\n> points at, or an empty string if the ref being shown is not a symref.\n\nI think this is reasonable, but:\n\n> +\tif (need_symref && (ref->flag & REF_ISSYMREF) && !ref->symref) {\n> +\t\tunsigned char unused1[20];\n> +\t\tconst char *symref;\n> +\t\tsymref = resolve_ref(ref->refname, unused1, 1, NULL);\n> +\t\tif (symref)\n> +\t\t\tref->symref = xstrdup(symref);\n> +\t\telse\n> +\t\t\tref->symref = \"\";\n> +\t}\n\nIt feels ugly that we need to re-resolve the ref when we simply threw\nthat information away earlier from when we called resolve_ref in\nget_ref_dir (which covers the loose case; for the packed case, I don't\nbelieve we have actual symbolic refs in the packed list).\n\nUnfortunately, passing that information up the callchain changes the\nsignature of each_ref_fn, which has a pretty big fallout. The patch is\nbelow (it does not replace your 3/4; it merely gets the information up\nto grab_single_ref).\n\nThe patch below is to show the extent of the change. The changes were\nmostly mechanical, and I haven't extensively tested. However, it\n_should_ be a no-op, as most callbacks just ignore the new information.\nThe exception is read_remote_branches, which was re-resolving just to\nfind symref information.\n\nIf we were going to do this for real, I would be tempted to actually\nchange the signature of each_ref_fn to take a struct so this doesn't\ncome up again, and do three patches:\n\n  1/3: pass \"struct reflist\" to each_ref_fn\n  2/3: add symref to \"struct reflist\"\n  3/3: use added symref information in read_remote_branches\n\n---\n bisect.c               |    2 +-\n builtin-branch.c       |    2 +-\n builtin-checkout.c     |    2 +-\n builtin-describe.c     |    2 +-\n builtin-fetch-pack.c   |    6 +++---\n builtin-fetch.c        |    2 +-\n builtin-for-each-ref.c |    2 +-\n builtin-fsck.c         |    6 +++---\n builtin-name-rev.c     |    2 +-\n builtin-pack-objects.c |    2 +-\n builtin-receive-pack.c |    4 ++--\n builtin-reflog.c       |    2 +-\n builtin-remote.c       |   15 ++++-----------\n builtin-replace.c      |    2 +-\n builtin-rev-parse.c    |    4 ++--\n builtin-show-branch.c  |   12 ++++++------\n builtin-show-ref.c     |    4 ++--\n builtin-tag.c          |    2 +-\n http-backend.c         |    2 +-\n log-tree.c             |    2 +-\n pack-refs.c            |    2 +-\n reachable.c            |    4 ++--\n refs.c                 |   32 ++++++++++++++++++++------------\n refs.h                 |    2 +-\n remote.c               |    4 ++--\n replace_object.c       |    3 ++-\n revision.c             |    4 ++--\n server-info.c          |    2 +-\n sha1_name.c            |    3 ++-\n transport.c            |    4 ++--\n upload-pack.c          |    4 ++--\n walker.c               |    2 +-\n 32 files changed, 73 insertions(+), 70 deletions(-)\n\ndiff --git a/bisect.c b/bisect.c\nindex 6dc27ee..e45f345 100644\n--- a/bisect.c\n+++ b/bisect.c\n@@ -436,7 +436,7 @@ static void sha1_array_push(struct sha1_array *array,\n }\n \n static int register_ref(const char *refname, const unsigned char *sha1,\n-\t\t\tint flags, void *cb_data)\n+\t\t\tint flags, const char *symref, void *cb_data)\n {\n \tif (!strcmp(refname, \"bad\")) {\n \t\tcurrent_bad_sha1 = sha1;\ndiff --git a/builtin-branch.c b/builtin-branch.c\nindex a28a139..8d43fb4 100644\n--- a/builtin-branch.c\n+++ b/builtin-branch.c\n@@ -257,7 +257,7 @@ static char *resolve_symref(const char *src, const char *prefix)\n \treturn xstrdup(dst);\n }\n \n-static int append_ref(const char *refname, const unsigned char *sha1, int flags, void *cb_data)\n+static int append_ref(const char *refname, const unsigned char *sha1, int flags, const char *symref, void *cb_data)\n {\n \tstruct ref_list *ref_list = (struct ref_list*)(cb_data);\n \tstruct ref_item *newitem;\ndiff --git a/builtin-checkout.c b/builtin-checkout.c\nindex 5277817..6e31bc6 100644\n--- a/builtin-checkout.c\n+++ b/builtin-checkout.c\n@@ -592,7 +592,7 @@ struct tracking_name_data {\n };\n \n static int check_tracking_name(const char *refname, const unsigned char *sha1,\n-\t\t\t       int flags, void *cb_data)\n+\t\t\t       int flags, const char *symref, void *cb_data)\n {\n \tstruct tracking_name_data *cb = cb_data;\n \tconst char *slash;\ndiff --git a/builtin-describe.c b/builtin-describe.c\nindex 71be2a9..5297a6f 100644\n--- a/builtin-describe.c\n+++ b/builtin-describe.c\n@@ -62,7 +62,7 @@ static void add_to_known_names(const char *path,\n \tfound_names = 1;\n }\n \n-static int get_name(const char *path, const unsigned char *sha1, int flag, void *cb_data)\n+static int get_name(const char *path, const unsigned char *sha1, int flag, const char *symref, void *cb_data)\n {\n \tint might_be_tag = !prefixcmp(path, \"refs/tags/\");\n \tstruct commit *commit;\ndiff --git a/builtin-fetch-pack.c b/builtin-fetch-pack.c\nindex 8ed4a6f..dfab784 100644\n--- a/builtin-fetch-pack.c\n+++ b/builtin-fetch-pack.c\n@@ -54,7 +54,7 @@ static void rev_list_push(struct commit *commit, int mark)\n \t}\n }\n \n-static int rev_list_insert_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)\n+static int rev_list_insert_ref(const char *path, const unsigned char *sha1, int flag, const char *symref, void *cb_data)\n {\n \tstruct object *o = deref_tag(parse_object(sha1), path, 0);\n \n@@ -64,7 +64,7 @@ static int rev_list_insert_ref(const char *path, const unsigned char *sha1, int\n \treturn 0;\n }\n \n-static int clear_marks(const char *path, const unsigned char *sha1, int flag, void *cb_data)\n+static int clear_marks(const char *path, const unsigned char *sha1, int flag, const char *symref, void *cb_data)\n {\n \tstruct object *o = deref_tag(parse_object(sha1), path, 0);\n \n@@ -422,7 +422,7 @@ done:\n \n static struct commit_list *complete;\n \n-static int mark_complete(const char *path, const unsigned char *sha1, int flag, void *cb_data)\n+static int mark_complete(const char *path, const unsigned char *sha1, int flag, const char *symref, void *cb_data)\n {\n \tstruct object *o = parse_object(sha1);\n \ndiff --git a/builtin-fetch.c b/builtin-fetch.c\nindex 55c7d94..cbbf46a 100644\n--- a/builtin-fetch.c\n+++ b/builtin-fetch.c\n@@ -533,7 +533,7 @@ static int prune_refs(struct transport *transport, struct ref *ref_map)\n }\n \n static int add_existing(const char *refname, const unsigned char *sha1,\n-\t\t\tint flag, void *cbdata)\n+\t\t\tint flag, const char *symref, void *cbdata)\n {\n \tstruct string_list *list = (struct string_list *)cbdata;\n \tstruct string_list_item *item = string_list_insert(refname, list);\ndiff --git a/builtin-for-each-ref.c b/builtin-for-each-ref.c\nindex a5a83f1..de43c09 100644\n--- a/builtin-for-each-ref.c\n+++ b/builtin-for-each-ref.c\n@@ -685,7 +685,7 @@ struct grab_ref_cbdata {\n  * need to use global variables to pass extra information to this\n  * function.\n  */\n-static int grab_single_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)\n+static int grab_single_ref(const char *refname, const unsigned char *sha1, int flag, const char *symref, void *cb_data)\n {\n \tstruct grab_ref_cbdata *cb = cb_data;\n \tstruct refinfo *ref;\ndiff --git a/builtin-fsck.c b/builtin-fsck.c\nindex 0929c7f..55f4996 100644\n--- a/builtin-fsck.c\n+++ b/builtin-fsck.c\n@@ -444,7 +444,7 @@ static int fsck_handle_reflog_ent(unsigned char *osha1, unsigned char *nsha1,\n \treturn 0;\n }\n \n-static int fsck_handle_reflog(const char *logname, const unsigned char *sha1, int flag, void *cb_data)\n+static int fsck_handle_reflog(const char *logname, const unsigned char *sha1, int flag, const char *symref, void *cb_data)\n {\n \tfor_each_reflog_ent(logname, fsck_handle_reflog_ent, NULL);\n \treturn 0;\n@@ -455,7 +455,7 @@ static int is_branch(const char *refname)\n \treturn !strcmp(refname, \"HEAD\") || !prefixcmp(refname, \"refs/heads/\");\n }\n \n-static int fsck_handle_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)\n+static int fsck_handle_ref(const char *refname, const unsigned char *sha1, int flag, const char *symref, void *cb_data)\n {\n \tstruct object *obj;\n \n@@ -477,7 +477,7 @@ static int fsck_handle_ref(const char *refname, const unsigned char *sha1, int f\n static void get_default_heads(void)\n {\n \tif (head_points_at && !is_null_sha1(head_sha1))\n-\t\tfsck_handle_ref(\"HEAD\", head_sha1, 0, NULL);\n+\t\tfsck_handle_ref(\"HEAD\", head_sha1, 0, NULL, NULL);\n \tfor_each_ref(fsck_handle_ref, NULL);\n \tif (include_reflogs)\n \t\tfor_each_reflog(fsck_handle_reflog, NULL);\ndiff --git a/builtin-name-rev.c b/builtin-name-rev.c\nindex 06a38ac..8b7ffb6 100644\n--- a/builtin-name-rev.c\n+++ b/builtin-name-rev.c\n@@ -88,7 +88,7 @@ struct name_ref_data {\n \tconst char *ref_filter;\n };\n \n-static int name_ref(const char *path, const unsigned char *sha1, int flags, void *cb_data)\n+static int name_ref(const char *path, const unsigned char *sha1, int flags, const char *symref, void *cb_data)\n {\n \tstruct object *o = parse_object(sha1);\n \tstruct name_ref_data *data = cb_data;\ndiff --git a/builtin-pack-objects.c b/builtin-pack-objects.c\nindex e1d3adf..acc24fc 100644\n--- a/builtin-pack-objects.c\n+++ b/builtin-pack-objects.c\n@@ -1766,7 +1766,7 @@ static void ll_find_deltas(struct object_entry **list, unsigned list_size,\n #define ll_find_deltas(l, s, w, d, p)\tfind_deltas(l, &s, w, d, p)\n #endif\n \n-static int add_ref_tag(const char *path, const unsigned char *sha1, int flag, void *cb_data)\n+static int add_ref_tag(const char *path, const unsigned char *sha1, int flag, const char *symref, void *cb_data)\n {\n \tunsigned char peeled[20];\n \ndiff --git a/builtin-receive-pack.c b/builtin-receive-pack.c\nindex 4320c93..1f22379 100644\n--- a/builtin-receive-pack.c\n+++ b/builtin-receive-pack.c\n@@ -103,7 +103,7 @@ static int receive_pack_config(const char *var, const char *value, void *cb)\n \treturn git_default_config(var, value, cb);\n }\n \n-static int show_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)\n+static int show_ref(const char *path, const unsigned char *sha1, int flag, const char *symref, void *cb_data)\n {\n \tif (!capabilities_to_send)\n \t\tpacket_write(1, \"%s %s\\n\", sha1_to_hex(sha1), path);\n@@ -118,7 +118,7 @@ static void write_head_info(void)\n {\n \tfor_each_ref(show_ref, NULL);\n \tif (capabilities_to_send)\n-\t\tshow_ref(\"capabilities^{}\", null_sha1, 0, NULL);\n+\t\tshow_ref(\"capabilities^{}\", null_sha1, 0, NULL, NULL);\n \n }\n \ndiff --git a/builtin-reflog.c b/builtin-reflog.c\nindex 7498210..5e13334 100644\n--- a/builtin-reflog.c\n+++ b/builtin-reflog.c\n@@ -383,7 +383,7 @@ static int expire_reflog(const char *ref, const unsigned char *sha1, int unused,\n \treturn status;\n }\n \n-static int collect_reflog(const char *ref, const unsigned char *sha1, int unused, void *cb_data)\n+static int collect_reflog(const char *ref, const unsigned char *sha1, int unused, const char *symref, void *cb_data)\n {\n \tstruct collected_reflog *e;\n \tstruct collect_reflog_cb *cb = cb_data;\ndiff --git a/builtin-remote.c b/builtin-remote.c\nindex 277765b..4cbd6fa 100644\n--- a/builtin-remote.c\n+++ b/builtin-remote.c\n@@ -456,7 +456,7 @@ struct branches_for_remote {\n };\n \n static int add_branch_for_removal(const char *refname,\n-\tconst unsigned char *sha1, int flags, void *cb_data)\n+\tconst unsigned char *sha1, int flags, const char *symref, void *cb_data)\n {\n \tstruct branches_for_remote *branches = cb_data;\n \tstruct refspec refspec;\n@@ -504,23 +504,16 @@ struct rename_info {\n };\n \n static int read_remote_branches(const char *refname,\n-\tconst unsigned char *sha1, int flags, void *cb_data)\n+\tconst unsigned char *sha1, int flags, const char *symref, void *cb_data)\n {\n \tstruct rename_info *rename = cb_data;\n \tstruct strbuf buf = STRBUF_INIT;\n \tstruct string_list_item *item;\n-\tint flag;\n-\tunsigned char orig_sha1[20];\n-\tconst char *symref;\n \n \tstrbuf_addf(&buf, \"refs/remotes/%s\", rename->old);\n \tif (!prefixcmp(refname, buf.buf)) {\n \t\titem = string_list_append(xstrdup(refname), rename->remote_branches);\n-\t\tsymref = resolve_ref(refname, orig_sha1, 1, &flag);\n-\t\tif (flag & REF_ISSYMREF)\n-\t\t\titem->util = xstrdup(symref);\n-\t\telse\n-\t\t\titem->util = NULL;\n+\t\titem->util = symref ? xstrdup(symref) : NULL;\n \t}\n \n \treturn 0;\n@@ -787,7 +780,7 @@ static void free_remote_ref_states(struct ref_states *states)\n }\n \n static int append_ref_to_tracked_list(const char *refname,\n-\tconst unsigned char *sha1, int flags, void *cb_data)\n+\tconst unsigned char *sha1, int flags, const char *symref, void *cb_data)\n {\n \tstruct ref_states *states = cb_data;\n \tstruct refspec refspec;\ndiff --git a/builtin-replace.c b/builtin-replace.c\nindex fe3a647..dc626d4 100644\n--- a/builtin-replace.c\n+++ b/builtin-replace.c\n@@ -21,7 +21,7 @@ static const char * const git_replace_usage[] = {\n };\n \n static int show_reference(const char *refname, const unsigned char *sha1,\n-\t\t\t  int flag, void *cb_data)\n+\t\t\t  int flag, const char *symref, void *cb_data)\n {\n \tconst char *pattern = cb_data;\n \ndiff --git a/builtin-rev-parse.c b/builtin-rev-parse.c\nindex a8c5043..7705b76 100644\n--- a/builtin-rev-parse.c\n+++ b/builtin-rev-parse.c\n@@ -178,13 +178,13 @@ static int show_default(void)\n \treturn 0;\n }\n \n-static int show_reference(const char *refname, const unsigned char *sha1, int flag, void *cb_data)\n+static int show_reference(const char *refname, const unsigned char *sha1, int flag, const char *symref, void *cb_data)\n {\n \tshow_rev(NORMAL, sha1, refname);\n \treturn 0;\n }\n \n-static int anti_reference(const char *refname, const unsigned char *sha1, int flag, void *cb_data)\n+static int anti_reference(const char *refname, const unsigned char *sha1, int flag, const char *symref, void *cb_data)\n {\n \tshow_rev(REVERSED, sha1, refname);\n \treturn 0;\ndiff --git a/builtin-show-branch.c b/builtin-show-branch.c\nindex 9f13caa..08fbff6 100644\n--- a/builtin-show-branch.c\n+++ b/builtin-show-branch.c\n@@ -403,7 +403,7 @@ static int append_ref(const char *refname, const unsigned char *sha1,\n \treturn 0;\n }\n \n-static int append_head_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)\n+static int append_head_ref(const char *refname, const unsigned char *sha1, int flag, const char *symref, void *cb_data)\n {\n \tunsigned char tmp[20];\n \tint ofs = 11;\n@@ -417,7 +417,7 @@ static int append_head_ref(const char *refname, const unsigned char *sha1, int f\n \treturn append_ref(refname + ofs, sha1, 0);\n }\n \n-static int append_remote_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)\n+static int append_remote_ref(const char *refname, const unsigned char *sha1, int flag, const char *symref, void *cb_data)\n {\n \tunsigned char tmp[20];\n \tint ofs = 13;\n@@ -431,7 +431,7 @@ static int append_remote_ref(const char *refname, const unsigned char *sha1, int\n \treturn append_ref(refname + ofs, sha1, 0);\n }\n \n-static int append_tag_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)\n+static int append_tag_ref(const char *refname, const unsigned char *sha1, int flag, const char *symref, void *cb_data)\n {\n \tif (prefixcmp(refname, \"refs/tags/\"))\n \t\treturn 0;\n@@ -449,7 +449,7 @@ static int count_slash(const char *s)\n \treturn cnt;\n }\n \n-static int append_matching_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)\n+static int append_matching_ref(const char *refname, const unsigned char *sha1, int flag, const char *symref, void *cb_data)\n {\n \t/* we want to allow pattern hold/<asterisk> to show all\n \t * branches under refs/heads/hold/, and v0.99.9? to show\n@@ -465,9 +465,9 @@ static int append_matching_ref(const char *refname, const unsigned char *sha1, i\n \tif (fnmatch(match_ref_pattern, tail, 0))\n \t\treturn 0;\n \tif (!prefixcmp(refname, \"refs/heads/\"))\n-\t\treturn append_head_ref(refname, sha1, flag, cb_data);\n+\t\treturn append_head_ref(refname, sha1, flag, symref, cb_data);\n \tif (!prefixcmp(refname, \"refs/tags/\"))\n-\t\treturn append_tag_ref(refname, sha1, flag, cb_data);\n+\t\treturn append_tag_ref(refname, sha1, flag, symref, cb_data);\n \treturn append_ref(refname, sha1, 0);\n }\n \ndiff --git a/builtin-show-ref.c b/builtin-show-ref.c\nindex 17ada88..5961f7f 100644\n--- a/builtin-show-ref.c\n+++ b/builtin-show-ref.c\n@@ -26,7 +26,7 @@ static void show_one(const char *refname, const unsigned char *sha1)\n \t\tprintf(\"%s %s\\n\", hex, refname);\n }\n \n-static int show_ref(const char *refname, const unsigned char *sha1, int flag, void *cbdata)\n+static int show_ref(const char *refname, const unsigned char *sha1, int flag, const char *symref, void *cbdata)\n {\n \tstruct object *obj;\n \tconst char *hex;\n@@ -102,7 +102,7 @@ match:\n \treturn 0;\n }\n \n-static int add_existing(const char *refname, const unsigned char *sha1, int flag, void *cbdata)\n+static int add_existing(const char *refname, const unsigned char *sha1, int flag, const char *symref, void *cbdata)\n {\n \tstruct string_list *list = (struct string_list *)cbdata;\n \tstring_list_insert(refname, list);\ndiff --git a/builtin-tag.c b/builtin-tag.c\nindex 4ef1c4f..ae9b78b 100644\n--- a/builtin-tag.c\n+++ b/builtin-tag.c\n@@ -32,7 +32,7 @@ struct tag_filter {\n #define PGP_SIGNATURE \"-----BEGIN PGP SIGNATURE-----\"\n \n static int show_reference(const char *refname, const unsigned char *sha1,\n-\t\t\t  int flag, void *cb_data)\n+\t\t\t  int flag, const char *symref, void *cb_data)\n {\n \tstruct tag_filter *filter = cb_data;\n \ndiff --git a/http-backend.c b/http-backend.c\nindex 345c12b..bd14606 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -419,7 +419,7 @@ static void run_service(const char **argv)\n }\n \n static int show_text_ref(const char *name, const unsigned char *sha1,\n-\tint flag, void *cb_data)\n+\tint flag, const char *symref, void *cb_data)\n {\n \tstruct strbuf *buf = cb_data;\n \tstruct object *o = parse_object(sha1);\ndiff --git a/log-tree.c b/log-tree.c\nindex 27afcf6..58a4ee8 100644\n--- a/log-tree.c\n+++ b/log-tree.c\n@@ -20,7 +20,7 @@ static void add_name_decoration(const char *prefix, const char *name, struct obj\n \tres->next = add_decoration(&name_decoration, obj, res);\n }\n \n-static int add_ref_decoration(const char *refname, const unsigned char *sha1, int flags, void *cb_data)\n+static int add_ref_decoration(const char *refname, const unsigned char *sha1, int flags, const char *symref, void *cb_data)\n {\n \tstruct object *obj = parse_object(sha1);\n \tif (!obj)\ndiff --git a/pack-refs.c b/pack-refs.c\nindex 7f43f8a..f1f3e73 100644\n--- a/pack-refs.c\n+++ b/pack-refs.c\n@@ -24,7 +24,7 @@ static int do_not_prune(int flags)\n }\n \n static int handle_one_ref(const char *path, const unsigned char *sha1,\n-\t\t\t  int flags, void *cb_data)\n+\t\t\t  int flags, const char *symref, void *cb_data)\n {\n \tstruct pack_refs_cb_data *cb = cb_data;\n \tint is_tag_ref;\ndiff --git a/reachable.c b/reachable.c\nindex b515fa2..2a07135 100644\n--- a/reachable.c\n+++ b/reachable.c\n@@ -133,7 +133,7 @@ static int add_one_reflog_ent(unsigned char *osha1, unsigned char *nsha1,\n \treturn 0;\n }\n \n-static int add_one_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)\n+static int add_one_ref(const char *path, const unsigned char *sha1, int flag, const char *symref, void *cb_data)\n {\n \tstruct object *object = parse_object(sha1);\n \tstruct rev_info *revs = (struct rev_info *)cb_data;\n@@ -145,7 +145,7 @@ static int add_one_ref(const char *path, const unsigned char *sha1, int flag, vo\n \treturn 0;\n }\n \n-static int add_one_reflog(const char *path, const unsigned char *sha1, int flag, void *cb_data)\n+static int add_one_reflog(const char *path, const unsigned char *sha1, int flag, const char *symref, void *cb_data)\n {\n \tfor_each_reflog_ent(path, add_one_reflog_ent, cb_data);\n \treturn 0;\ndiff --git a/refs.c b/refs.c\nindex 503a8c2..986c8e2 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -10,6 +10,7 @@\n struct ref_list {\n \tstruct ref_list *next;\n \tunsigned char flag; /* ISSYMREF? ISPACKED? */\n+\tchar *symref;\n \tunsigned char sha1[20];\n \tunsigned char peeled[20];\n \tchar name[FLEX_ARRAY];\n@@ -44,7 +45,8 @@ static const char *parse_ref_line(char *line, unsigned char *sha1)\n }\n \n static struct ref_list *add_ref(const char *name, const unsigned char *sha1,\n-\t\t\t\tint flag, struct ref_list *list,\n+\t\t\t\tint flag, const char *real_ref,\n+\t\t\t\tstruct ref_list *list,\n \t\t\t\tstruct ref_list **new_entry)\n {\n \tint len;\n@@ -57,6 +59,7 @@ static struct ref_list *add_ref(const char *name, const unsigned char *sha1,\n \thashclr(entry->peeled);\n \tmemcpy(entry->name, name, len);\n \tentry->flag = flag;\n+\tentry->symref = (flag & REF_ISSYMREF) ? xstrdup(real_ref) : NULL;\n \tentry->next = list;\n \tif (new_entry)\n \t\t*new_entry = entry;\n@@ -204,7 +207,7 @@ static void read_packed_refs(FILE *f, struct cached_refs *cached_refs)\n \n \t\tname = parse_ref_line(refline, sha1);\n \t\tif (name) {\n-\t\t\tlist = add_ref(name, sha1, flag, list, &last);\n+\t\t\tlist = add_ref(name, sha1, flag, NULL, list, &last);\n \t\t\tcontinue;\n \t\t}\n \t\tif (last &&\n@@ -219,7 +222,7 @@ static void read_packed_refs(FILE *f, struct cached_refs *cached_refs)\n \n void add_extra_ref(const char *name, const unsigned char *sha1, int flag)\n {\n-\textra_refs = add_ref(name, sha1, flag, extra_refs, NULL);\n+\textra_refs = add_ref(name, sha1, flag, NULL, extra_refs, NULL);\n }\n \n void clear_extra_refs(void)\n@@ -260,6 +263,7 @@ static struct ref_list *get_ref_dir(const char *base, struct ref_list *list)\n \t\t\tstruct stat st;\n \t\t\tint flag;\n \t\t\tint namelen;\n+\t\t\tconst char *real_ref;\n \n \t\t\tif (de->d_name[0] == '.')\n \t\t\t\tcontinue;\n@@ -275,9 +279,10 @@ static struct ref_list *get_ref_dir(const char *base, struct ref_list *list)\n \t\t\t\tlist = get_ref_dir(ref, list);\n \t\t\t\tcontinue;\n \t\t\t}\n-\t\t\tif (!resolve_ref(ref, sha1, 1, &flag))\n+\t\t\treal_ref = resolve_ref(ref, sha1, 1, &flag);\n+\t\t\tif (!real_ref)\n \t\t\t\thashclr(sha1);\n-\t\t\tlist = add_ref(ref, sha1, flag, list, NULL);\n+\t\t\tlist = add_ref(ref, sha1, flag, real_ref, list, NULL);\n \t\t}\n \t\tfree(ref);\n \t\tclosedir(dir);\n@@ -292,7 +297,7 @@ struct warn_if_dangling_data {\n };\n \n static int warn_if_dangling_symref(const char *refname, const unsigned char *sha1,\n-\t\t\t\t   int flags, void *cb_data)\n+\t\t\t\t   int flags, const char *symref, void *cb_data)\n {\n \tstruct warn_if_dangling_data *d = cb_data;\n \tconst char *resolves_to;\n@@ -549,16 +554,17 @@ static int do_one_ref(const char *base, each_ref_fn fn, int trim,\n \t\t}\n \t}\n \tcurrent_ref = entry;\n-\treturn fn(entry->name + trim, entry->sha1, entry->flag, cb_data);\n+\treturn fn(entry->name + trim, entry->sha1, entry->flag, entry->symref,\n+\t\t\tcb_data);\n }\n \n static int filter_refs(const char *ref, const unsigned char *sha, int flags,\n-\tvoid *data)\n+\t\tconst char *symref, void *data)\n {\n \tstruct ref_filter *filter = (struct ref_filter *)data;\n \tif (fnmatch(filter->pattern, ref, 0))\n \t\treturn 0;\n-\treturn filter->fn(ref, sha, flags, filter->cb_data);\n+\treturn filter->fn(ref, sha, flags, symref, filter->cb_data);\n }\n \n int peel_ref(const char *ref, unsigned char *sha1)\n@@ -654,9 +660,11 @@ int head_ref(each_ref_fn fn, void *cb_data)\n {\n \tunsigned char sha1[20];\n \tint flag;\n+\tconst char *real_ref;\n \n-\tif (resolve_ref(\"HEAD\", sha1, 1, &flag))\n-\t\treturn fn(\"HEAD\", sha1, flag, cb_data);\n+\treal_ref = resolve_ref(\"HEAD\", sha1, 1, &flag);\n+\tif (real_ref)\n+\t\treturn fn(\"HEAD\", sha1, flag, real_ref, cb_data);\n \treturn 0;\n }\n \n@@ -1666,7 +1674,7 @@ static int do_for_each_reflog(const char *base, each_ref_fn fn, void *cb_data)\n \t\t\t\tif (!resolve_ref(log, sha1, 0, NULL))\n \t\t\t\t\tretval = error(\"bad ref for %s\", log);\n \t\t\t\telse\n-\t\t\t\t\tretval = fn(log, sha1, 0, cb_data);\n+\t\t\t\t\tretval = fn(log, sha1, 0, NULL, cb_data);\n \t\t\t}\n \t\t\tif (retval)\n \t\t\t\tbreak;\ndiff --git a/refs.h b/refs.h\nindex f7648b9..300ffb3 100644\n--- a/refs.h\n+++ b/refs.h\n@@ -17,7 +17,7 @@ struct ref_lock {\n  * Calls the specified function for each ref file until it returns nonzero,\n  * and returns the value\n  */\n-typedef int each_ref_fn(const char *refname, const unsigned char *sha1, int flags, void *cb_data);\n+typedef int each_ref_fn(const char *refname, const unsigned char *sha1, int flags, const char *symref, void *cb_data);\n extern int head_ref(each_ref_fn, void *);\n extern int for_each_ref(each_ref_fn, void *);\n extern int for_each_ref_in(const char *, each_ref_fn, void *);\ndiff --git a/remote.c b/remote.c\nindex c70181c..b78805a 100644\n--- a/remote.c\n+++ b/remote.c\n@@ -1612,7 +1612,7 @@ int format_tracking_info(struct branch *branch, struct strbuf *sb)\n \treturn 1;\n }\n \n-static int one_local_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)\n+static int one_local_ref(const char *refname, const unsigned char *sha1, int flag, const char *symref, void *cb_data)\n {\n \tstruct ref ***local_tail = cb_data;\n \tstruct ref *ref;\n@@ -1684,7 +1684,7 @@ struct stale_heads_info {\n };\n \n static int get_stale_heads_cb(const char *refname,\n-\tconst unsigned char *sha1, int flags, void *cb_data)\n+\tconst unsigned char *sha1, int flags, const char *symref, void *cb_data)\n {\n \tstruct stale_heads_info *info = cb_data;\n \tstruct refspec refspec;\ndiff --git a/replace_object.c b/replace_object.c\nindex eb59604..1dd6965 100644\n--- a/replace_object.c\n+++ b/replace_object.c\n@@ -52,7 +52,8 @@ static int register_replace_object(struct replace_object *replace,\n \n static int register_replace_ref(const char *refname,\n \t\t\t\tconst unsigned char *sha1,\n-\t\t\t\tint flag, void *cb_data)\n+\t\t\t\tint flag, const char *symref,\n+\t\t\t\tvoid *cb_data)\n {\n \t/* Get sha1 from refname */\n \tconst char *slash = strrchr(refname, '/');\ndiff --git a/revision.c b/revision.c\nindex 3ba6d99..65cec90 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -701,7 +701,7 @@ struct all_refs_cb {\n \tconst char *name_for_errormsg;\n };\n \n-static int handle_one_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)\n+static int handle_one_ref(const char *path, const unsigned char *sha1, int flag, const char *symref, void *cb_data)\n {\n \tstruct all_refs_cb *cb = cb_data;\n \tstruct object *object = get_reference(cb->all_revs, path, sha1,\n@@ -751,7 +751,7 @@ static int handle_one_reflog_ent(unsigned char *osha1, unsigned char *nsha1,\n \treturn 0;\n }\n \n-static int handle_one_reflog(const char *path, const unsigned char *sha1, int flag, void *cb_data)\n+static int handle_one_reflog(const char *path, const unsigned char *sha1, int flag, const char *symref, void *cb_data)\n {\n \tstruct all_refs_cb *cb = cb_data;\n \tcb->warned_bad_reflog = 0;\ndiff --git a/server-info.c b/server-info.c\nindex 4098ca2..f617f3f 100644\n--- a/server-info.c\n+++ b/server-info.c\n@@ -7,7 +7,7 @@\n /* refs */\n static FILE *info_ref_fp;\n \n-static int add_info_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)\n+static int add_info_ref(const char *path, const unsigned char *sha1, int flag, const char *symref, void *cb_data)\n {\n \tstruct object *o = parse_object(sha1);\n \tif (!o)\ndiff --git a/sha1_name.c b/sha1_name.c\nindex 7729925..aba8bf3 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -661,7 +661,8 @@ static int get_sha1_1(const char *name, int len, unsigned char *sha1)\n }\n \n static int handle_one_ref(const char *path,\n-\t\tconst unsigned char *sha1, int flag, void *cb_data)\n+\t\tconst unsigned char *sha1, int flag, const char *symref,\n+\t\tvoid *cb_data)\n {\n \tstruct commit_list **list = cb_data;\n \tstruct object *object = parse_object(sha1);\ndiff --git a/transport.c b/transport.c\nindex 3846aac..039ccef 100644\n--- a/transport.c\n+++ b/transport.c\n@@ -283,7 +283,7 @@ static int fetch_objs_via_rsync(struct transport *transport,\n }\n \n static int write_one_ref(const char *name, const unsigned char *sha1,\n-\t\tint flags, void *data)\n+\t\tint flags, const char *symref, void *data)\n {\n \tstruct strbuf *buf = data;\n \tint len = buf->len;\n@@ -316,7 +316,7 @@ static int write_refs_to_temp_dir(struct strbuf *temp_dir,\n \t\tif (dwim_ref(refspec[i], strlen(refspec[i]), sha1, &ref) != 1)\n \t\t\treturn error(\"Could not get ref %s\", refspec[i]);\n \n-\t\tif (write_one_ref(ref, sha1, 0, temp_dir)) {\n+\t\tif (write_one_ref(ref, sha1, 0, NULL, temp_dir)) {\n \t\t\tfree(ref);\n \t\t\treturn -1;\n \t\t}\ndiff --git a/upload-pack.c b/upload-pack.c\nindex df15181..8f3c730 100644\n--- a/upload-pack.c\n+++ b/upload-pack.c\n@@ -618,7 +618,7 @@ static void receive_needs(void)\n \tfree(shallows.objects);\n }\n \n-static int send_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)\n+static int send_ref(const char *refname, const unsigned char *sha1, int flag, const char *symref, void *cb_data)\n {\n \tstatic const char *capabilities = \"multi_ack thin-pack side-band\"\n \t\t\" side-band-64k ofs-delta shallow no-progress\"\n@@ -646,7 +646,7 @@ static int send_ref(const char *refname, const unsigned char *sha1, int flag, vo\n \treturn 0;\n }\n \n-static int mark_our_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)\n+static int mark_our_ref(const char *refname, const unsigned char *sha1, int flag, const char *symref, void *cb_data)\n {\n \tstruct object *o = parse_object(sha1);\n \tif (!o)\ndiff --git a/walker.c b/walker.c\nindex 11d9052..0b2aaf6 100644\n--- a/walker.c\n+++ b/walker.c\n@@ -202,7 +202,7 @@ static int interpret_target(struct walker *walker, char *target, unsigned char *\n \treturn -1;\n }\n \n-static int mark_complete(const char *path, const unsigned char *sha1, int flag, void *cb_data)\n+static int mark_complete(const char *path, const unsigned char *sha1, int flag, const char *symref, void *cb_data)\n {\n \tstruct commit *commit = lookup_commit_reference_gently(sha1, 1);\n \tif (commit) {\n"},{"id":"134526","messageId":"7vy6iwp0oy.fsf@alter.siamese.dyndns.org","threadId":"22645","inReplyTo":"20100214063243.GA20630@coredump.intra.peff.net","subject":"Re: [PATCH 3/4] for-each-ref --format='%(symref) %(symref:short)'","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-02-14T10:32:29Z","receivedAt":"2010-02-14T10:32:29Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> It feels ugly that we need to re-resolve the ref when we simply threw\n> that information away earlier from when we called resolve_ref in\n> get_ref_dir...\n\nIt is true and I indeed thought about it while doing the patch, but \"how\noften would we see symref in the entire refs list, and what percentage of\ncallers would benefit from seeing this information?\" stopped me from going\nfurther in that direction.\n\n> ...\n> If we were going to do this for real, I would be tempted to actually\n> change the signature of each_ref_fn to take a struct so this doesn't\n> come up again.\n\nThat would actually be sensible.  Adding symref parameter all over just so\nthat we do not have to re-resolve symbolic refs in a few codepaths feels\nlike a \"it would have been nicer if things were that way from day one, but\nhow much does that churn really buys us now\" kind of change, but carrying\nthe full information around in the internal API is a \"right thing to do\".\n"},{"id":"134631","messageId":"20100215083924.GA13636@coredump.intra.peff.net","threadId":"22645","inReplyTo":"7vy6iwp0oy.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 3/4] for-each-ref --format='%(symref) %(symref:short)'","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-02-15T08:39:24Z","receivedAt":"2010-02-15T08:39:24Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sun, Feb 14, 2010 at 02:32:29AM -0800, Junio C Hamano wrote:\n\n> Jeff King <peff@peff.net> writes:\n> \n> > It feels ugly that we need to re-resolve the ref when we simply threw\n> > that information away earlier from when we called resolve_ref in\n> > get_ref_dir...\n> \n> It is true and I indeed thought about it while doing the patch, but \"how\n> often would we see symref in the entire refs list, and what percentage of\n> callers would benefit from seeing this information?\" stopped me from going\n> further in that direction.\n\nIt is really only two code-paths (the one I mentioned, and the new one\nyou are adding). I was thinking that we had to pay the resolve_ref cost\nfor _every_ ref, symref or not, but that is not the case. Because we\npass along the flag, we can re-resolve only the few that need it.\n\nSo there is even less efficiency to be gained than I at first thought.\nLet's just drop it, as it is such an invasive change for no good reason.\n\n-Peff\n"}]}