git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 05/19] list-objects-filters: add omit-large-blobs filter

From
JHJeff Hostetler <git@jeffhostetler.com>
Date
Jul 13, 2017, 17:34 UTC
Message-ID
<20170713173459.3559-6-git@jeffhostetler.com>
In-Reply-To
<20170713173459.3559-1-git@jeffhostetler.com>
From: Jeff Hostetler <jeffhost@microsoft.com>

Create a filter for traverse_commit_list_filtered() to omit blobs larger than a requested size from the result, but always include ".git*" special files.

This filter will be used in a future commit by rev-list and pack-objects for partial/narrow clone/fetch.

Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
---
 list-objects-filters.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++
 list-objects-filters.h | 12 +++++++
 2 files changed, 109 insertions(+)
diff --git a/list-objects-filters.c b/list-objects-filters.c
index f29d8bc..f04d70e 100644
--- a/list-objects-filters.c
+++ b/list-objects-filters.c
@@ -83,3 +83,100 @@ void traverse_commit_list_omit_all_blobs(
 
 	oidset2_clear(&d.omits);
 }
+
+/*
+ * A filter for list-objects to omit large blobs,
+ * but always include ".git*" special files.
+ */
+struct filter_omit_large_blobs_data {
+	struct oidset2 omits;
+	int64_t max_bytes;
+};
+
+static list_objects_filter_result filter_omit_large_blobs(
+	list_objects_filter_type filter_type,
+	struct object *obj,
+	const char *pathname,
+	const char *filename,
+	void *filter_data_)
+{
+	struct filter_omit_large_blobs_data *filter_data = filter_data_;
+	int64_t object_length = -1;
+	unsigned long s;
+	enum object_type t;
+
+	switch (filter_type) {
+	default:
+		die("unkown filter_type");
+		return LOFR_ZERO;
+
+	case LOFT_BEGIN_TREE:
+		assert(obj->type == OBJ_TREE);
+		/* always include all tree objects */
+		return LOFR_MARK_SEEN | LOFR_SHOW;
+
+	case LOFT_END_TREE:
+		assert(obj->type == OBJ_TREE);
+		return LOFR_ZERO;
+
+	case LOFT_BLOB:
+		assert(obj->type == OBJ_BLOB);
+		assert((obj->flags & SEEN) == 0);
+
+		/*
+		 * If previously provisionally omitted (because of size), see if the
+		 * current filename is special and force it to be included.
+		 */
+		if (oidset2_contains(&filter_data->omits, &obj->oid)) {
+			if ((strncmp(filename, ".git", 4) == 0) && filename[4]) {
+				oidset2_remove(&filter_data->omits, &obj->oid);
+				return LOFR_MARK_SEEN | LOFR_SHOW;
+			}
+			return LOFR_ZERO; /* continue provisionally omitting it */
+		}
+
+		t = sha1_object_info(obj->oid.hash, &s);
+		assert(t == OBJ_BLOB);
+		object_length = (int64_t)((uint64_t)(s));
+
+		if (object_length < filter_data->max_bytes)
+			return LOFR_MARK_SEEN | LOFR_SHOW;
+
+		/*
+		 * Provisionally omit it.  We've already established that this blob
+		 * is too big and doesn't have a special filename, so we WANT to
+		 * omit it.  However, there may be a special file elsewhere in the
+		 * tree that references this same blob, so we cannot reject it yet.
+		 * Leave the LOFR_ bits unset so that if the blob appears again in
+		 * the traversal, we will be asked again.
+		 *
+		 * No need for a pathname, since we only test for special filenames
+		 * above.
+		 */
+		oidset2_insert(&filter_data->omits, &obj->oid, object_length,
+			       NULL);
+		return LOFR_ZERO;
+	}
+}
+
+void traverse_commit_list_omit_large_blobs(
+	struct rev_info *revs,
+	show_commit_fn show_commit,
+	show_object_fn show_object,
+	oidset2_foreach_cb print_omitted_object,
+	void *ctx_data,
+	int64_t large_byte_limit)
+{
+	struct filter_omit_large_blobs_data d;
+
+	memset(&d, 0, sizeof(d));
+	d.max_bytes = large_byte_limit;
+
+	traverse_commit_list_filtered(revs, show_commit, show_object, ctx_data,
+				      filter_omit_large_blobs, &d);
+
+	if (print_omitted_object)
+		oidset2_foreach(&d.omits, print_omitted_object, ctx_data);
+
+	oidset2_clear(&d.omits);
+}
diff --git a/list-objects-filters.h b/list-objects-filters.h
index b981020..32b2833 100644
--- a/list-objects-filters.h
+++ b/list-objects-filters.h
@@ -14,4 +14,16 @@ void traverse_commit_list_omit_all_blobs(
 	oidset2_foreach_cb print_omitted_object,
 	void *ctx_data);
 
+/*
+ * A filter for list-objects to omit large blobs,
+ * but always include ".git*" special files.
+ */
+void traverse_commit_list_omit_large_blobs(
+	struct rev_info *revs,
+	show_commit_fn show_commit,
+	show_object_fn show_object,
+	oidset2_foreach_cb print_omitted_object,
+	void *ctx_data,
+	int64_t large_byte_limit);
+
 #endif /* LIST_OBJECTS_FILTERS_H */
-- 
2.9.3
Previous: Jeff HostetlerNext: Jeff Hostetler
Message 19 of 20 in “WIP object filtering for partial clone”
  1. 00/19 WIP object filtering for partial cloneJeff Hostetler, Jul 13, 2017
  2. 01/19 dir: refactor add_excludes()Jeff Hostetler, Jul 13, 2017
  3. 03/19 list-objects: filter objects in traverse_commit_listJeff Hostetler, Jul 13, 2017
  4. 06/19 list-objects-filters: add use-sparse-checkout filterJeff Hostetler, Jul 13, 2017
  5. 07/19 object-filter: common declarations for object filteringJeff Hostetler, Jul 13, 2017
  6. 11/19 pack-objects: add object filtering supportJeff Hostetler, Jul 13, 2017
  7. 10/19 t6112: rev-list object filtering testJeff Hostetler, Jul 13, 2017
  8. 13/19 upload-pack: add filter-objects to protocol documentationJeff Hostetler, Jul 13, 2017
  9. 17/19 clone: add filter argumentsJeff Hostetler, Jul 13, 2017
  10. 18/19 index-pack: relax consistency checks for omitted objectsJeff Hostetler, Jul 13, 2017
  11. 12/19 pack-objects: add filtering help textJeff Hostetler, Jul 13, 2017
  12. 14/19 upload-pack: add object filteringJeff Hostetler, Jul 13, 2017
  13. 15/19 fetch-pack: add object filtering supportJeff Hostetler, Jul 13, 2017
  14. 16/19 connected: add filter_allow_omitted option to APIJeff Hostetler, Jul 13, 2017
  15. 19/19 fetch: add object filtering to fetchJeff Hostetler, Jul 13, 2017
  16. 08/19 rev-list: add object filtering supportJeff Hostetler, Jul 13, 2017
  17. 09/19 rev-list: add filtering help textJeff Hostetler, Jul 13, 2017
  18. 02/19 oidset2: create oidset subclass with object length and pathnameJeff Hostetler, Jul 13, 2017
  19. 05/19 list-objects-filters: add omit-large-blobs filterJeff Hostetler, Jul 13, 2017
  20. 04/19 list-objects-filters: add omit-all-blobs filterJeff Hostetler, Jul 13, 2017

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.