diff options
Diffstat (limited to 'third_party/git/builtin/rev-list.c')
-rw-r--r-- | third_party/git/builtin/rev-list.c | 126 |
1 files changed, 29 insertions, 97 deletions
diff --git a/third_party/git/builtin/rev-list.c b/third_party/git/builtin/rev-list.c index f520111eda09..301ccb970bb3 100644 --- a/third_party/git/builtin/rev-list.c +++ b/third_party/git/builtin/rev-list.c @@ -18,6 +18,7 @@ #include "reflog-walk.h" #include "oidset.h" #include "packfile.h" +#include "object-store.h" static const char rev_list_usage[] = "git rev-list [OPTION] <commit-id>... [ -- paths... ]\n" @@ -253,26 +254,11 @@ static int finish_object(struct object *obj, const char *name, void *cb_data) static void show_object(struct object *obj, const char *name, void *cb_data) { struct rev_list_info *info = cb_data; - struct rev_info *revs = info->revs; - if (finish_object(obj, name, cb_data)) return; display_progress(progress, ++progress_counter); if (info->flags & REV_LIST_QUIET) return; - - if (revs->count) { - /* - * The object count is always accumulated in the .count_right - * field for traversal that is not a left-right traversal, - * and cmd_rev_list() made sure that a .count request that - * wants to count non-commit objects, which is handled by - * the show_object() callback, does not ask for .left_right. - */ - revs->count_right++; - return; - } - if (arg_show_object_names) show_object_with_name(stdout, obj, name); else @@ -379,79 +365,6 @@ static inline int parse_missing_action_value(const char *value) return 0; } -static int try_bitmap_count(struct rev_info *revs, - struct list_objects_filter_options *filter) -{ - uint32_t commit_count = 0, - tag_count = 0, - tree_count = 0, - blob_count = 0; - int max_count; - struct bitmap_index *bitmap_git; - - /* This function only handles counting, not general traversal. */ - if (!revs->count) - return -1; - - /* - * A bitmap result can't know left/right, etc, because we don't - * actually traverse. - */ - if (revs->left_right || revs->cherry_mark) - return -1; - - /* - * If we're counting reachable objects, we can't handle a max count of - * commits to traverse, since we don't know which objects go with which - * commit. - */ - if (revs->max_count >= 0 && - (revs->tag_objects || revs->tree_objects || revs->blob_objects)) - return -1; - - /* - * This must be saved before doing any walking, since the revision - * machinery will count it down to zero while traversing. - */ - max_count = revs->max_count; - - bitmap_git = prepare_bitmap_walk(revs, filter); - if (!bitmap_git) - return -1; - - count_bitmap_commit_list(bitmap_git, &commit_count, - revs->tree_objects ? &tree_count : NULL, - revs->blob_objects ? &blob_count : NULL, - revs->tag_objects ? &tag_count : NULL); - if (max_count >= 0 && max_count < commit_count) - commit_count = max_count; - - printf("%d\n", commit_count + tree_count + blob_count + tag_count); - free_bitmap_index(bitmap_git); - return 0; -} - -static int try_bitmap_traversal(struct rev_info *revs, - struct list_objects_filter_options *filter) -{ - struct bitmap_index *bitmap_git; - - /* - * We can't use a bitmap result with a traversal limit, since the set - * of commits we'd get would be essentially random. - */ - if (revs->max_count >= 0) - return -1; - - bitmap_git = prepare_bitmap_walk(revs, filter); - if (!bitmap_git) - return -1; - - traverse_bitmap_commit_list(bitmap_git, revs, &show_object_fast); - free_bitmap_index(bitmap_git); - return 0; -} - int cmd_rev_list(int argc, const char **argv, const char *prefix) { struct rev_info revs; @@ -558,6 +471,10 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix) parse_list_objects_filter(&filter_options, arg); if (filter_options.choice && !revs.blob_objects) die(_("object filtering requires --objects")); + if (filter_options.choice == LOFC_SPARSE_OID && + !filter_options.sparse_oid_value) + die(_("invalid sparse value '%s'"), + filter_options.filter_spec); continue; } if (!strcmp(arg, ("--no-" CL_ARG__FILTER))) { @@ -609,10 +526,8 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix) if (revs.show_notes) die(_("rev-list does not support display of notes")); - if (revs.count && - (revs.tag_objects || revs.tree_objects || revs.blob_objects) && - (revs.left_right || revs.cherry_mark)) - die(_("marked counting is incompatible with --objects")); + if (filter_options.choice && use_bitmap_index) + die(_("cannot combine --use-bitmap-index with object filtering")); save_commit_buffer = (revs.verbose_header || revs.grep_filter.pattern_list || @@ -623,11 +538,28 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix) if (show_progress) progress = start_delayed_progress(show_progress, 0); - if (use_bitmap_index) { - if (!try_bitmap_count(&revs, &filter_options)) - return 0; - if (!try_bitmap_traversal(&revs, &filter_options)) - return 0; + if (use_bitmap_index && !revs.prune) { + if (revs.count && !revs.left_right && !revs.cherry_mark) { + uint32_t commit_count; + int max_count = revs.max_count; + struct bitmap_index *bitmap_git; + if ((bitmap_git = prepare_bitmap_walk(&revs))) { + count_bitmap_commit_list(bitmap_git, &commit_count, NULL, NULL, NULL); + if (max_count >= 0 && max_count < commit_count) + commit_count = max_count; + printf("%d\n", commit_count); + free_bitmap_index(bitmap_git); + return 0; + } + } else if (revs.max_count < 0 && + revs.tag_objects && revs.tree_objects && revs.blob_objects) { + struct bitmap_index *bitmap_git; + if ((bitmap_git = prepare_bitmap_walk(&revs))) { + traverse_bitmap_commit_list(bitmap_git, &show_object_fast); + free_bitmap_index(bitmap_git); + return 0; + } + } } if (prepare_revision_walk(&revs)) |