{"thread":{"id":"19539","subject":"[PATCH 1/2] for-each-ref: Do not lookup objects when they will not be used","startedAt":"2009-05-27T19:23:12Z","lastAt":"2009-05-27T19:24:41Z","messageCount":2,"participants":["Anders Kaseorg"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"114829","messageId":"alpine.DEB.2.00.0905271518540.24169@vinegar-pot.mit.edu","threadId":"19539","inReplyTo":null,"subject":"[PATCH 1/2] for-each-ref: Do not lookup objects when they will not be used","fromName":"Anders Kaseorg","fromEmail":"andersk@mit.edu","sentAt":"2009-05-27T19:23:12Z","receivedAt":"2009-05-27T19:23:12Z","isPatch":true,"sender":{"key":"andersk@mit.edu","avatar":"https://avatars.githubusercontent.com/u/26471?v=4"},"body":"This makes commands such as `git for-each-ref --format='%(refname)'`, \nwhich are used heavily by the bash_completion code, run about 6 times \nfaster on an uncached repository (3 s intead of 18 s on my linux-2.6 \nrepository with several remotes).\n\nSigned-off-by: Anders Kaseorg <andersk@mit.edu>\n---\n builtin-for-each-ref.c |   26 +++++++++++++++++---------\n 1 files changed, 17 insertions(+), 9 deletions(-)\n\ndiff --git a/builtin-for-each-ref.c b/builtin-for-each-ref.c\nindex d091e04..1911cda 100644\n--- a/builtin-for-each-ref.c\n+++ b/builtin-for-each-ref.c\n@@ -561,14 +561,6 @@ static void populate_value(struct refinfo *ref)\n \n \tref->value = xcalloc(sizeof(struct atom_value), used_atom_cnt);\n \n-\tbuf = get_obj(ref->objectname, &obj, &size, &eaten);\n-\tif (!buf)\n-\t\tdie(\"missing object %s for %s\",\n-\t\t    sha1_to_hex(ref->objectname), ref->refname);\n-\tif (!obj)\n-\t\tdie(\"parse_object_buffer failed on %s for %s\",\n-\t\t    sha1_to_hex(ref->objectname), ref->refname);\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@@ -621,6 +613,22 @@ static void populate_value(struct refinfo *ref)\n \t\t}\n \t}\n \n+\tfor (i = 0; i < used_atom_cnt; i++) {\n+\t\tstruct atom_value *v = &ref->value[i];\n+\t\tif (v->s == NULL)\n+\t\t\tgoto need_obj;\n+\t}\n+\treturn;\n+\n+ need_obj:\n+\tbuf = get_obj(ref->objectname, &obj, &size, &eaten);\n+\tif (!buf)\n+\t\tdie(\"missing object %s for %s\",\n+\t\t    sha1_to_hex(ref->objectname), ref->refname);\n+\tif (!obj)\n+\t\tdie(\"parse_object_buffer failed on %s for %s\",\n+\t\t    sha1_to_hex(ref->objectname), ref->refname);\n+\n \tgrab_values(ref->value, 0, obj, buf, size);\n \tif (!eaten)\n \t\tfree(buf);\n@@ -926,7 +934,7 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)\n \n \tmemset(&cbdata, 0, sizeof(cbdata));\n \tcbdata.grab_pattern = argv;\n-\tfor_each_ref(grab_single_ref, &cbdata);\n+\tfor_each_rawref(grab_single_ref, &cbdata);\n \trefs = cbdata.grab_array;\n \tnum_refs = cbdata.grab_cnt;\n \n-- \n1.6.3.1\n"},{"id":"114830","messageId":"alpine.DEB.2.00.0905271523541.24169@vinegar-pot.mit.edu","threadId":"19539","inReplyTo":"alpine.DEB.2.00.0905271518540.24169@vinegar-pot.mit.edu","subject":"[PATCH 2/2] branch: Do not lookup commits when they will not be used","fromName":"Anders Kaseorg","fromEmail":"andersk@mit.edu","sentAt":"2009-05-27T19:24:41Z","receivedAt":"2009-05-27T19:24:41Z","isPatch":true,"sender":{"key":"andersk@mit.edu","avatar":"https://avatars.githubusercontent.com/u/26471?v=4"},"body":"This makes `git branch` without -v, --merged, --no-merged, or --contains \nrun about 5 times faster on an uncached repository (4 s intead of 18 s on \nmy linux-2.6 repository with several remotes).\n\nSigned-off-by: Anders Kaseorg <andersk@mit.edu>\n---\n builtin-branch.c |   33 ++++++++++++++++++++-------------\n 1 files changed, 20 insertions(+), 13 deletions(-)\n\ndiff --git a/builtin-branch.c b/builtin-branch.c\nindex 91098ca..7ca2834 100644\n--- a/builtin-branch.c\n+++ b/builtin-branch.c\n@@ -195,6 +195,7 @@ struct ref_list {\n \tstruct ref_item *list;\n \tstruct commit_list *with_commit;\n \tint kinds;\n+\tint lookup_commits;\n };\n \n static char *resolve_symref(const char *src, const char *prefix)\n@@ -215,7 +216,7 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,\n {\n \tstruct ref_list *ref_list = (struct ref_list*)(cb_data);\n \tstruct ref_item *newitem;\n-\tstruct commit *commit;\n+\tstruct commit *commit = NULL;\n \tint kind, i;\n \tconst char *prefix, *orig_refname = refname;\n \n@@ -240,21 +241,25 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,\n \tif (ARRAY_SIZE(ref_kind) <= i)\n \t\treturn 0;\n \n-\tcommit = lookup_commit_reference_gently(sha1, 1);\n-\tif (!commit)\n-\t\treturn error(\"branch '%s' does not point at a commit\", refname);\n-\n-\t/* Filter with with_commit if specified */\n-\tif (!is_descendant_of(commit, ref_list->with_commit))\n-\t\treturn 0;\n-\n \t/* Don't add types the caller doesn't want */\n \tif ((kind & ref_list->kinds) == 0)\n \t\treturn 0;\n \n-\tif (merge_filter != NO_FILTER)\n-\t\tadd_pending_object(&ref_list->revs,\n-\t\t\t\t   (struct object *)commit, refname);\n+\n+\tif (ref_list->lookup_commits) {\n+\t\tcommit = lookup_commit_reference_gently(sha1, 1);\n+\t\tif (!commit)\n+\t\t\treturn error(\"branch '%s' does not point at a commit\",\n+\t\t\t\t     refname);\n+\n+\t\t/* Filter with with_commit if specified */\n+\t\tif (!is_descendant_of(commit, ref_list->with_commit))\n+\t\t\treturn 0;\n+\n+\t\tif (merge_filter != NO_FILTER)\n+\t\t\tadd_pending_object(&ref_list->revs,\n+\t\t\t\t\t   (struct object *)commit, refname);\n+\t}\n \n \t/* Resize buffer */\n \tif (ref_list->index >= ref_list->alloc) {\n@@ -426,7 +431,9 @@ static void print_ref_list(int kinds, int detached, int verbose, int abbrev, str\n \tref_list.with_commit = with_commit;\n \tif (merge_filter != NO_FILTER)\n \t\tinit_revisions(&ref_list.revs, NULL);\n-\tfor_each_ref(append_ref, &ref_list);\n+\tref_list.lookup_commits =\n+\t    with_commit || merge_filter != NO_FILTER || verbose;\n+\tfor_each_rawref(append_ref, &ref_list);\n \tif (merge_filter != NO_FILTER) {\n \t\tstruct commit *filter;\n \t\tfilter = lookup_commit_reference_gently(merge_filter_ref, 0);\n-- \n1.6.3.1\n"}]}