aboutsummaryrefslogtreecommitdiffstats
path: root/list-objects-filter.c
diff options
context:
space:
mode:
Diffstat (limited to 'list-objects-filter.c')
-rw-r--r--list-objects-filter.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/list-objects-filter.c b/list-objects-filter.c
index 0ebfa52966..1c1ee3d1bb 100644
--- a/list-objects-filter.c
+++ b/list-objects-filter.c
@@ -545,6 +545,81 @@ static void filter_sparse_oid__init(
filter->free_fn = filter_sparse_free;
}
+/*
+ * A filter for list-objects to omit large blobs.
+ * And to OPTIONALLY collect a list of the omitted OIDs.
+ */
+struct filter_object_type_data {
+ enum object_type object_type;
+};
+
+static enum list_objects_filter_result filter_object_type(
+ struct repository *r,
+ enum list_objects_filter_situation filter_situation,
+ struct object *obj,
+ const char *pathname,
+ const char *filename,
+ struct oidset *omits,
+ void *filter_data_)
+{
+ struct filter_object_type_data *filter_data = filter_data_;
+
+ switch (filter_situation) {
+ default:
+ BUG("unknown filter_situation: %d", filter_situation);
+
+ case LOFS_TAG:
+ assert(obj->type == OBJ_TAG);
+ if (filter_data->object_type == OBJ_TAG)
+ return LOFR_MARK_SEEN | LOFR_DO_SHOW;
+ return LOFR_MARK_SEEN;
+
+ case LOFS_COMMIT:
+ assert(obj->type == OBJ_COMMIT);
+ if (filter_data->object_type == OBJ_COMMIT)
+ return LOFR_MARK_SEEN | LOFR_DO_SHOW;
+ return LOFR_MARK_SEEN;
+
+ case LOFS_BEGIN_TREE:
+ assert(obj->type == OBJ_TREE);
+
+ /*
+ * If we only want to show commits or tags, then there is no
+ * need to walk down trees.
+ */
+ if (filter_data->object_type == OBJ_COMMIT ||
+ filter_data->object_type == OBJ_TAG)
+ return LOFR_SKIP_TREE;
+
+ if (filter_data->object_type == OBJ_TREE)
+ return LOFR_MARK_SEEN | LOFR_DO_SHOW;
+
+ return LOFR_MARK_SEEN;
+
+ case LOFS_BLOB:
+ assert(obj->type == OBJ_BLOB);
+
+ if (filter_data->object_type == OBJ_BLOB)
+ return LOFR_MARK_SEEN | LOFR_DO_SHOW;
+ return LOFR_MARK_SEEN;
+
+ case LOFS_END_TREE:
+ return LOFR_ZERO;
+ }
+}
+
+static void filter_object_type__init(
+ struct list_objects_filter_options *filter_options,
+ struct filter *filter)
+{
+ struct filter_object_type_data *d = xcalloc(1, sizeof(*d));
+ d->object_type = filter_options->object_type;
+
+ filter->filter_data = d;
+ filter->filter_object_fn = filter_object_type;
+ filter->free_fn = free;
+}
+
/* A filter which only shows objects shown by all sub-filters. */
struct combine_filter_data {
struct subfilter *sub;
@@ -691,6 +766,7 @@ static filter_init_fn s_filters[] = {
filter_blobs_limit__init,
filter_trees_depth__init,
filter_sparse_oid__init,
+ filter_object_type__init,
filter_combine__init,
};