rev-list: allow filtering of provided items
When providing an object filter, it is currently impossible to also filter provided items. E.g. when executing `git rev-list HEAD` , the commit this reference points to will be treated as user-provided and is thus excluded from the filtering mechanism. This makes it harder than necessary to properly use the new `--filter=object:type` filter given that even if the user wants to only see blobs, he'll still see commits of provided references. Improve this by introducing a new `--filter-provided-objects` option to the git-rev-parse(1) command. If given, then all user-provided references will be subject to filtering. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>maint
parent
169a15ebd6
commit
9cf68b27d5
|
@ -933,6 +933,11 @@ equivalent.
|
|||
--no-filter::
|
||||
Turn off any previous `--filter=` argument.
|
||||
|
||||
--filter-provided-objects::
|
||||
Filter the list of explicitly provided objects, which would otherwise
|
||||
always be printed even if they did not match any of the filters. Only
|
||||
useful with `--filter=`.
|
||||
|
||||
--filter-print-omitted::
|
||||
Only useful with `--filter=`; prints a list of the objects omitted
|
||||
by the filter. Object IDs are prefixed with a ``~'' character.
|
||||
|
|
|
@ -3516,7 +3516,7 @@ static int pack_options_allow_reuse(void)
|
|||
|
||||
static int get_object_list_from_bitmap(struct rev_info *revs)
|
||||
{
|
||||
if (!(bitmap_git = prepare_bitmap_walk(revs, &filter_options)))
|
||||
if (!(bitmap_git = prepare_bitmap_walk(revs, &filter_options, 0)))
|
||||
return -1;
|
||||
|
||||
if (pack_options_allow_reuse() &&
|
||||
|
|
|
@ -398,7 +398,8 @@ static inline int parse_missing_action_value(const char *value)
|
|||
}
|
||||
|
||||
static int try_bitmap_count(struct rev_info *revs,
|
||||
struct list_objects_filter_options *filter)
|
||||
struct list_objects_filter_options *filter,
|
||||
int filter_provided_objects)
|
||||
{
|
||||
uint32_t commit_count = 0,
|
||||
tag_count = 0,
|
||||
|
@ -433,7 +434,7 @@ static int try_bitmap_count(struct rev_info *revs,
|
|||
*/
|
||||
max_count = revs->max_count;
|
||||
|
||||
bitmap_git = prepare_bitmap_walk(revs, filter);
|
||||
bitmap_git = prepare_bitmap_walk(revs, filter, filter_provided_objects);
|
||||
if (!bitmap_git)
|
||||
return -1;
|
||||
|
||||
|
@ -450,7 +451,8 @@ static int try_bitmap_count(struct rev_info *revs,
|
|||
}
|
||||
|
||||
static int try_bitmap_traversal(struct rev_info *revs,
|
||||
struct list_objects_filter_options *filter)
|
||||
struct list_objects_filter_options *filter,
|
||||
int filter_provided_objects)
|
||||
{
|
||||
struct bitmap_index *bitmap_git;
|
||||
|
||||
|
@ -461,7 +463,7 @@ static int try_bitmap_traversal(struct rev_info *revs,
|
|||
if (revs->max_count >= 0)
|
||||
return -1;
|
||||
|
||||
bitmap_git = prepare_bitmap_walk(revs, filter);
|
||||
bitmap_git = prepare_bitmap_walk(revs, filter, filter_provided_objects);
|
||||
if (!bitmap_git)
|
||||
return -1;
|
||||
|
||||
|
@ -471,14 +473,15 @@ static int try_bitmap_traversal(struct rev_info *revs,
|
|||
}
|
||||
|
||||
static int try_bitmap_disk_usage(struct rev_info *revs,
|
||||
struct list_objects_filter_options *filter)
|
||||
struct list_objects_filter_options *filter,
|
||||
int filter_provided_objects)
|
||||
{
|
||||
struct bitmap_index *bitmap_git;
|
||||
|
||||
if (!show_disk_usage)
|
||||
return -1;
|
||||
|
||||
bitmap_git = prepare_bitmap_walk(revs, filter);
|
||||
bitmap_git = prepare_bitmap_walk(revs, filter, filter_provided_objects);
|
||||
if (!bitmap_git)
|
||||
return -1;
|
||||
|
||||
|
@ -499,6 +502,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
|
|||
int bisect_show_vars = 0;
|
||||
int bisect_find_all = 0;
|
||||
int use_bitmap_index = 0;
|
||||
int filter_provided_objects = 0;
|
||||
const char *show_progress = NULL;
|
||||
|
||||
if (argc == 2 && !strcmp(argv[1], "-h"))
|
||||
|
@ -599,6 +603,10 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
|
|||
list_objects_filter_set_no_filter(&filter_options);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "--filter-provided-objects")) {
|
||||
filter_provided_objects = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "--filter-print-omitted")) {
|
||||
arg_print_omitted = 1;
|
||||
continue;
|
||||
|
@ -665,11 +673,11 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
|
|||
progress = start_delayed_progress(show_progress, 0);
|
||||
|
||||
if (use_bitmap_index) {
|
||||
if (!try_bitmap_count(&revs, &filter_options))
|
||||
if (!try_bitmap_count(&revs, &filter_options, filter_provided_objects))
|
||||
return 0;
|
||||
if (!try_bitmap_disk_usage(&revs, &filter_options))
|
||||
if (!try_bitmap_disk_usage(&revs, &filter_options, filter_provided_objects))
|
||||
return 0;
|
||||
if (!try_bitmap_traversal(&revs, &filter_options))
|
||||
if (!try_bitmap_traversal(&revs, &filter_options, filter_provided_objects))
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -694,6 +702,16 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
|
|||
return show_bisect_vars(&info, reaches, all);
|
||||
}
|
||||
|
||||
if (filter_provided_objects) {
|
||||
struct commit_list *c;
|
||||
for (i = 0; i < revs.pending.nr; i++) {
|
||||
struct object_array_entry *pending = revs.pending.objects + i;
|
||||
pending->item->flags |= NOT_USER_GIVEN;
|
||||
}
|
||||
for (c = revs.commits; c; c = c->next)
|
||||
c->item->object.flags |= NOT_USER_GIVEN;
|
||||
}
|
||||
|
||||
if (arg_print_omitted)
|
||||
oidset_init(&omitted_objects, DEFAULT_OIDSET_SIZE);
|
||||
if (arg_missing_action == MA_PRINT)
|
||||
|
|
|
@ -986,7 +986,8 @@ static int can_filter_bitmap(struct list_objects_filter_options *filter)
|
|||
}
|
||||
|
||||
struct bitmap_index *prepare_bitmap_walk(struct rev_info *revs,
|
||||
struct list_objects_filter_options *filter)
|
||||
struct list_objects_filter_options *filter,
|
||||
int filter_provided_objects)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
|
@ -1081,7 +1082,8 @@ struct bitmap_index *prepare_bitmap_walk(struct rev_info *revs,
|
|||
if (haves_bitmap)
|
||||
bitmap_and_not(wants_bitmap, haves_bitmap);
|
||||
|
||||
filter_bitmap(bitmap_git, wants, wants_bitmap, filter);
|
||||
filter_bitmap(bitmap_git, (filter && filter_provided_objects) ? NULL : wants,
|
||||
wants_bitmap, filter);
|
||||
|
||||
bitmap_git->result = wants_bitmap;
|
||||
bitmap_git->haves = haves_bitmap;
|
||||
|
|
|
@ -50,7 +50,8 @@ void traverse_bitmap_commit_list(struct bitmap_index *,
|
|||
show_reachable_fn show_reachable);
|
||||
void test_bitmap_walk(struct rev_info *revs);
|
||||
struct bitmap_index *prepare_bitmap_walk(struct rev_info *revs,
|
||||
struct list_objects_filter_options *filter);
|
||||
struct list_objects_filter_options *filter,
|
||||
int filter_provided_objects);
|
||||
int reuse_partial_packfile_from_bitmap(struct bitmap_index *,
|
||||
struct packed_git **packfile,
|
||||
uint32_t *entries,
|
||||
|
|
|
@ -223,7 +223,7 @@ void mark_reachable_objects(struct rev_info *revs, int mark_reflog,
|
|||
cp.progress = progress;
|
||||
cp.count = 0;
|
||||
|
||||
bitmap_git = prepare_bitmap_walk(revs, NULL);
|
||||
bitmap_git = prepare_bitmap_walk(revs, NULL, 0);
|
||||
if (bitmap_git) {
|
||||
traverse_bitmap_commit_list(bitmap_git, revs, mark_object_seen);
|
||||
free_bitmap_index(bitmap_git);
|
||||
|
|
|
@ -203,6 +203,34 @@ test_expect_success 'verify object:type=tag prints tag' '
|
|||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_expect_success 'verify object:type=blob prints only blob with --filter-provided-objects' '
|
||||
printf "%s blob\n" $(git -C object-type rev-parse HEAD:blob) >expected &&
|
||||
git -C object-type rev-list --objects \
|
||||
--filter=object:type=blob --filter-provided-objects HEAD >actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_expect_success 'verify object:type=tree prints only tree with --filter-provided-objects' '
|
||||
printf "%s \n" $(git -C object-type rev-parse HEAD^{tree}) >expected &&
|
||||
git -C object-type rev-list --objects \
|
||||
--filter=object:type=tree HEAD --filter-provided-objects >actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_expect_success 'verify object:type=commit prints only commit with --filter-provided-objects' '
|
||||
git -C object-type rev-parse HEAD >expected &&
|
||||
git -C object-type rev-list --objects \
|
||||
--filter=object:type=commit --filter-provided-objects HEAD >actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_expect_success 'verify object:type=tag prints only tag with --filter-provided-objects' '
|
||||
printf "%s tag\n" $(git -C object-type rev-parse tag) >expected &&
|
||||
git -C object-type rev-list --objects \
|
||||
--filter=object:type=tag --filter-provided-objects tag >actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
# Test sparse:path=<path> filter.
|
||||
# !!!!
|
||||
# NOTE: sparse:path filter support has been dropped for security reasons,
|
||||
|
|
|
@ -98,6 +98,28 @@ test_expect_success 'object:type filter' '
|
|||
test_bitmap_traversal expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'object:type filter with --filter-provided-objects' '
|
||||
git rev-list --objects --filter-provided-objects --filter=object:type=tag tag >expect &&
|
||||
git rev-list --use-bitmap-index \
|
||||
--objects --filter-provided-objects --filter=object:type=tag tag >actual &&
|
||||
test_cmp expect actual &&
|
||||
|
||||
git rev-list --objects --filter-provided-objects --filter=object:type=commit tag >expect &&
|
||||
git rev-list --use-bitmap-index \
|
||||
--objects --filter-provided-objects --filter=object:type=commit tag >actual &&
|
||||
test_bitmap_traversal expect actual &&
|
||||
|
||||
git rev-list --objects --filter-provided-objects --filter=object:type=tree tag >expect &&
|
||||
git rev-list --use-bitmap-index \
|
||||
--objects --filter-provided-objects --filter=object:type=tree tag >actual &&
|
||||
test_bitmap_traversal expect actual &&
|
||||
|
||||
git rev-list --objects --filter-provided-objects --filter=object:type=blob tag >expect &&
|
||||
git rev-list --use-bitmap-index \
|
||||
--objects --filter-provided-objects --filter=object:type=blob tag >actual &&
|
||||
test_bitmap_traversal expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'combine filter' '
|
||||
git rev-list --objects --filter=blob:limit=1000 --filter=object:type=blob tag >expect &&
|
||||
git rev-list --use-bitmap-index \
|
||||
|
@ -105,4 +127,18 @@ test_expect_success 'combine filter' '
|
|||
test_bitmap_traversal expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'combine filter with --filter-provided-objects' '
|
||||
git rev-list --objects --filter-provided-objects --filter=blob:limit=1000 --filter=object:type=blob tag >expect &&
|
||||
git rev-list --use-bitmap-index \
|
||||
--objects --filter-provided-objects --filter=blob:limit=1000 --filter=object:type=blob tag >actual &&
|
||||
test_bitmap_traversal expect actual &&
|
||||
|
||||
git cat-file --batch-check="%(objecttype) %(objectsize)" <actual >objects &&
|
||||
while read objecttype objectsize
|
||||
do
|
||||
test "$objecttype" = blob || return 1
|
||||
test "$objectsize" -le 1000 || return 1
|
||||
done <objects
|
||||
'
|
||||
|
||||
test_done
|
||||
|
|
Loading…
Reference in New Issue