If you want to verify a ref, it is overkill to first read all loose refs into a linked list, and then check if the desired ref is there. Signed-off-by: Johannes Schindelin <Johannes.Schindelin@xxxxxx> --- This is kind of quick and dirty. An alternative would be to pack the tags _per default_. I once argued for that, but it appears nobody liked that idea. I even proposed to pack _all_ refs, and I still think this would be a good idea. However, HTTP/FTP transport would have to learn about that long before, and/or a config option would be needed to allow public repos to cater for older clients. Isn't it a bug that --verify succeeds, if only _one_ ref passed to the command exists? builtin-show-ref.c | 14 +++++++++++++- refs.c | 17 +++++++++++------ refs.h | 1 + 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/builtin-show-ref.c b/builtin-show-ref.c index 0739798..b57b074 100644 --- a/builtin-show-ref.c +++ b/builtin-show-ref.c @@ -157,7 +157,19 @@ int cmd_show_ref(int argc, const char **argv, const char *prefix) } if (show_head) head_ref(show_ref, NULL); - for_each_ref(show_ref, NULL); + if (verify) { + for (i = 0; pattern[i]; i++) + if (!access(git_path(pattern[i]), R_OK)) { + unsigned char sha1[20]; + if (resolve_ref(pattern[i], sha1, 1, NULL)) { + found_match++; + printf("%s %s\n", sha1_to_hex(sha1), + pattern[i]); + } + } + for_each_packed_ref(show_ref, NULL); + } else + for_each_ref(show_ref, NULL); if (!found_match) { if (verify && !quiet) die("No match"); diff --git a/refs.c b/refs.c index a02957c..7e6a459 100644 --- a/refs.c +++ b/refs.c @@ -413,11 +413,11 @@ int peel_ref(const char *ref, unsigned char *sha1) } static int do_for_each_ref(const char *base, each_ref_fn fn, int trim, - void *cb_data) + void *cb_data, int packed_only) { int retval; struct ref_list *packed = get_packed_refs(); - struct ref_list *loose = get_loose_refs(); + struct ref_list *loose = packed_only ? NULL : get_loose_refs(); while (packed && loose) { struct ref_list *entry; @@ -456,24 +456,29 @@ int head_ref(each_ref_fn fn, void *cb_data) return 0; } +int for_each_packed_ref(each_ref_fn fn, void *cb_data) +{ + return do_for_each_ref("refs/", fn, 0, cb_data, 1); +} + int for_each_ref(each_ref_fn fn, void *cb_data) { - return do_for_each_ref("refs/", fn, 0, cb_data); + return do_for_each_ref("refs/", fn, 0, cb_data, 0); } int for_each_tag_ref(each_ref_fn fn, void *cb_data) { - return do_for_each_ref("refs/tags/", fn, 10, cb_data); + return do_for_each_ref("refs/tags/", fn, 10, cb_data, 0); } int for_each_branch_ref(each_ref_fn fn, void *cb_data) { - return do_for_each_ref("refs/heads/", fn, 11, cb_data); + return do_for_each_ref("refs/heads/", fn, 11, cb_data, 0); } int for_each_remote_ref(each_ref_fn fn, void *cb_data) { - return do_for_each_ref("refs/remotes/", fn, 13, cb_data); + return do_for_each_ref("refs/remotes/", fn, 13, cb_data, 0); } /* NEEDSWORK: This is only used by ssh-upload and it should go; the diff --git a/refs.h b/refs.h index 51aab1e..0cfe7b5 100644 --- a/refs.h +++ b/refs.h @@ -19,6 +19,7 @@ struct ref_lock { */ typedef int each_ref_fn(const char *refname, const unsigned char *sha1, int flags, void *cb_data); extern int head_ref(each_ref_fn, void *); +extern int for_each_packed_ref(each_ref_fn, void *); extern int for_each_ref(each_ref_fn, void *); extern int for_each_tag_ref(each_ref_fn, void *); extern int for_each_branch_ref(each_ref_fn, void *); - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html