diff options
Diffstat (limited to 'list-objects-filter.c')
-rw-r--r-- | list-objects-filter.c | 77 |
1 files changed, 67 insertions, 10 deletions
diff --git a/list-objects-filter.c b/list-objects-filter.c index a0ba78b..a62624a 100644 --- a/list-objects-filter.c +++ b/list-objects-filter.c @@ -34,6 +34,7 @@ struct filter_blobs_none_data { }; static enum list_objects_filter_result filter_blobs_none( + struct repository *r, enum list_objects_filter_situation filter_situation, struct object *obj, const char *pathname, @@ -44,8 +45,7 @@ static enum list_objects_filter_result filter_blobs_none( switch (filter_situation) { default: - die("unknown filter_situation"); - return LOFR_ZERO; + BUG("unknown filter_situation: %d", filter_situation); case LOFS_BEGIN_TREE: assert(obj->type == OBJ_TREE); @@ -81,6 +81,62 @@ static void *filter_blobs_none__init( } /* + * A filter for list-objects to omit ALL trees and blobs from the traversal. + * Can OPTIONALLY collect a list of the omitted OIDs. + */ +struct filter_trees_none_data { + struct oidset *omits; +}; + +static enum list_objects_filter_result filter_trees_none( + struct repository *r, + enum list_objects_filter_situation filter_situation, + struct object *obj, + const char *pathname, + const char *filename, + void *filter_data_) +{ + struct filter_trees_none_data *filter_data = filter_data_; + + switch (filter_situation) { + default: + BUG("unknown filter_situation: %d", filter_situation); + + case LOFS_BEGIN_TREE: + case LOFS_BLOB: + if (filter_data->omits) { + oidset_insert(filter_data->omits, &obj->oid); + /* _MARK_SEEN but not _DO_SHOW (hard omit) */ + return LOFR_MARK_SEEN; + } else { + /* + * Not collecting omits so no need to to traverse tree. + */ + return LOFR_SKIP_TREE | LOFR_MARK_SEEN; + } + + case LOFS_END_TREE: + assert(obj->type == OBJ_TREE); + return LOFR_ZERO; + + } +} + +static void* filter_trees_none__init( + struct oidset *omitted, + struct list_objects_filter_options *filter_options, + filter_object_fn *filter_fn, + filter_free_fn *filter_free_fn) +{ + struct filter_trees_none_data *d = xcalloc(1, sizeof(*d)); + d->omits = omitted; + + *filter_fn = filter_trees_none; + *filter_free_fn = free; + return d; +} + +/* * A filter for list-objects to omit large blobs. * And to OPTIONALLY collect a list of the omitted OIDs. */ @@ -90,6 +146,7 @@ struct filter_blobs_limit_data { }; static enum list_objects_filter_result filter_blobs_limit( + struct repository *r, enum list_objects_filter_situation filter_situation, struct object *obj, const char *pathname, @@ -102,8 +159,7 @@ static enum list_objects_filter_result filter_blobs_limit( switch (filter_situation) { default: - die("unknown filter_situation"); - return LOFR_ZERO; + BUG("unknown filter_situation: %d", filter_situation); case LOFS_BEGIN_TREE: assert(obj->type == OBJ_TREE); @@ -118,7 +174,7 @@ static enum list_objects_filter_result filter_blobs_limit( assert(obj->type == OBJ_BLOB); assert((obj->flags & SEEN) == 0); - t = oid_object_info(the_repository, &obj->oid, &object_length); + t = oid_object_info(r, &obj->oid, &object_length); if (t != OBJ_BLOB) { /* probably OBJ_NONE */ /* * We DO NOT have the blob locally, so we cannot @@ -196,6 +252,7 @@ struct filter_sparse_data { }; static enum list_objects_filter_result filter_sparse( + struct repository *r, enum list_objects_filter_situation filter_situation, struct object *obj, const char *pathname, @@ -208,15 +265,14 @@ static enum list_objects_filter_result filter_sparse( switch (filter_situation) { default: - die("unknown filter_situation"); - return LOFR_ZERO; + BUG("unknown filter_situation: %d", filter_situation); case LOFS_BEGIN_TREE: assert(obj->type == OBJ_TREE); dtype = DT_DIR; val = is_excluded_from_list(pathname, strlen(pathname), filename, &dtype, &filter_data->el, - &the_index); + r->index); if (val < 0) val = filter_data->array_frame[filter_data->nr].defval; @@ -279,7 +335,7 @@ static enum list_objects_filter_result filter_sparse( dtype = DT_REG; val = is_excluded_from_list(pathname, strlen(pathname), filename, &dtype, &filter_data->el, - &the_index); + r->index); if (val < 0) val = frame->defval; if (val > 0) { @@ -374,6 +430,7 @@ static filter_init_fn s_filters[] = { NULL, filter_blobs_none__init, filter_blobs_limit__init, + filter_trees_none__init, filter_sparse_oid__init, filter_sparse_path__init, }; @@ -389,7 +446,7 @@ void *list_objects_filter__init( assert((sizeof(s_filters) / sizeof(s_filters[0])) == LOFC__COUNT); if (filter_options->choice >= LOFC__COUNT) - die("invalid list-objects filter choice: %d", + BUG("invalid list-objects filter choice: %d", filter_options->choice); init_fn = s_filters[filter_options->choice]; |