From: Junio C Hamano Date: Thu, 28 Dec 2017 22:08:50 +0000 (-0800) Subject: Merge branch 'sb/describe-blob' X-Git-Tag: v2.16.0-rc0~1 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/556de1a8e38ff03d31fd35751582447001f39d0c Merge branch 'sb/describe-blob' "git describe" was taught to dig trees deeper to find a : that refers to a given blob object. * sb/describe-blob: builtin/describe.c: describe a blob builtin/describe.c: factor out describe_commit builtin/describe.c: print debug statements earlier builtin/describe.c: rename `oid` to avoid variable shadowing revision.h: introduce blob/tree walking in order of the commits list-objects.c: factor out traverse_trees_and_blobs t6120: fix typo in test name --- 556de1a8e38ff03d31fd35751582447001f39d0c diff --cc list-objects.c index d9e83d05e1,4caa6fcb77..0966cdc9fa --- a/list-objects.c +++ b/list-objects.c @@@ -214,27 -183,15 +214,17 @@@ static void add_pending_tree(struct rev add_pending_object(revs, &tree->object, ""); } - static void do_traverse(struct rev_info *revs, - show_commit_fn show_commit, - show_object_fn show_object, - void *show_data, - filter_object_fn filter_fn, - void *filter_data) + static void traverse_trees_and_blobs(struct rev_info *revs, + struct strbuf *base, + show_object_fn show_object, - void *data) ++ void *show_data, ++ filter_object_fn filter_fn, ++ void *filter_data) { int i; - struct commit *commit; - struct strbuf base; - strbuf_init(&base, PATH_MAX); - while ((commit = get_revision(revs)) != NULL) { - /* - * an uninteresting boundary commit may not have its tree - * parsed yet, but we are not going to show them anyway - */ - if (commit->tree) - add_pending_tree(revs, commit->tree); - show_commit(commit, show_data); - } + assert(base->len == 0); + for (i = 0; i < revs->pending.nr; i++) { struct object_array_entry *pending = revs->pending.objects + i; struct object *obj = pending->item; @@@ -251,47 -208,47 +241,82 @@@ path = ""; if (obj->type == OBJ_TREE) { process_tree(revs, (struct tree *)obj, show_object, - &base, path, show_data, - base, path, data); ++ base, path, show_data, + filter_fn, filter_data); continue; } if (obj->type == OBJ_BLOB) { process_blob(revs, (struct blob *)obj, show_object, - &base, path, show_data, - base, path, data); ++ base, path, show_data, + filter_fn, filter_data); continue; } die("unknown pending object %s (%s)", oid_to_hex(&obj->oid), name); } object_array_clear(&revs->pending); - strbuf_release(&base); + } + -void traverse_commit_list(struct rev_info *revs, - show_commit_fn show_commit, - show_object_fn show_object, - void *data) ++static void do_traverse(struct rev_info *revs, ++ show_commit_fn show_commit, ++ show_object_fn show_object, ++ void *show_data, ++ filter_object_fn filter_fn, ++ void *filter_data) + { + struct commit *commit; + struct strbuf csp; /* callee's scratch pad */ + strbuf_init(&csp, PATH_MAX); + + while ((commit = get_revision(revs)) != NULL) { + /* + * an uninteresting boundary commit may not have its tree + * parsed yet, but we are not going to show them anyway + */ + if (commit->tree) + add_pending_tree(revs, commit->tree); - show_commit(commit, data); ++ show_commit(commit, show_data); + + if (revs->tree_blobs_in_commit_order) + /* + * NEEDSWORK: Adding the tree and then flushing it here + * needs a reallocation for each commit. Can we pass the + * tree directory without allocation churn? + */ - traverse_trees_and_blobs(revs, &csp, show_object, data); ++ traverse_trees_and_blobs(revs, &csp, ++ show_object, show_data, ++ filter_fn, filter_data); + } - traverse_trees_and_blobs(revs, &csp, show_object, data); - ++ traverse_trees_and_blobs(revs, &csp, ++ show_object, show_data, ++ filter_fn, filter_data); + strbuf_release(&csp); } + +void traverse_commit_list(struct rev_info *revs, + show_commit_fn show_commit, + show_object_fn show_object, + void *show_data) +{ + do_traverse(revs, show_commit, show_object, show_data, NULL, NULL); +} + +void traverse_commit_list_filtered( + struct list_objects_filter_options *filter_options, + struct rev_info *revs, + show_commit_fn show_commit, + show_object_fn show_object, + void *show_data, + struct oidset *omitted) +{ + filter_object_fn filter_fn = NULL; + filter_free_fn filter_free_fn = NULL; + void *filter_data = NULL; + + filter_data = list_objects_filter__init(omitted, filter_options, + &filter_fn, &filter_free_fn); + do_traverse(revs, show_commit, show_object, show_data, + filter_fn, filter_data); + if (filter_data && filter_free_fn) + filter_free_fn(filter_data); +}