From: Teng Long <dyroneteng@xxxxxxxxx> This commit introduce the exclusion of tree objects. The exclusion range is designed by an enum named `exclude_level` in "pack-objects.c" that enumerate three values, "ET_SELF", "ET_INCLUDE" and "ET_REACHABLE". Exclusion scope on different level: 1. When a tree is specified to be excluded with level "ET_SELF", only the tree object itself will be excluded. 2. When a tree specified to be excluded with level "ET_INCLUDE", exclude the tree itself, as well as all the trees and blobs it contains. 3. When it is specified with level "ET_REACHABLE", the excluding scope is as same as level "ET_INCLUDE", because tree do not have any ancestors. Signed-off-by: Teng Long <dyroneteng@xxxxxxxxx> --- builtin/pack-objects.c | 18 ++++++++++++++++++ list-objects.c | 8 ++++++-- object.c | 1 + object.h | 1 + 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index e7b27ef443..6713e734fb 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -1250,6 +1250,21 @@ static int match_packfile_uri_exclusions(struct configured_exclusion *ex) return 0; } +static int want_exclude_object(struct object_list *objects) +{ + struct object_list *p; + struct configured_exclusion *ex; + + if (!objects) + return 0; + for (p = objects; p; p = p->next) { + ex = oidmap_get(&configured_exclusions, &p->item->oid); + if (match_packfile_uri_exclusions(ex) && ex->level > ET_SELF) + return 1; + } + return 0; +} + static int want_found_object(const struct object_id *oid, int exclude, struct packed_git *p) { @@ -1400,11 +1415,14 @@ static int want_object_in_pack(const struct object_id *oid, if (uri_protocols.nr) { if (referred_objs) { struct commit *commit = referred_objs->commit; + struct object_list *trees = referred_objs->trees; if (commit) { commit_ex = oidmap_get(&configured_exclusions, &commit->object.oid); if (match_packfile_uri_exclusions(commit_ex) && commit_ex->level > ET_SELF) return 0; } + if (want_exclude_object(trees)) + return 0; } ex = oidmap_get(&configured_exclusions, oid); diff --git a/list-objects.c b/list-objects.c index b32213ecf1..40292e2cc8 100644 --- a/list-objects.c +++ b/list-objects.c @@ -114,8 +114,11 @@ static void process_tree_contents(struct traversal_context *ctx, struct name_entry entry; enum interesting match = ctx->revs->diffopt.pathspec.nr == 0 ? all_entries_interesting : entry_not_interesting; + struct referred_objects *referred_buf; init_tree_desc(&desc, tree->buffer, tree->size); + referred_buf = xmemdupz(referred_objs, sizeof(struct referred_objects)); + object_list_insert(&tree->object, &referred_buf->trees); while (tree_entry(&desc, &entry)) { if (match != all_entries_interesting) { @@ -136,7 +139,7 @@ static void process_tree_contents(struct traversal_context *ctx, entry.path, oid_to_hex(&tree->object.oid)); } t->object.flags |= NOT_USER_GIVEN; - process_tree(ctx, t, base, entry.path, referred_objs); + process_tree(ctx, t, base, entry.path, referred_buf); } else if (S_ISGITLINK(entry.mode)) process_gitlink(ctx, entry.oid.hash, @@ -149,9 +152,10 @@ static void process_tree_contents(struct traversal_context *ctx, entry.path, oid_to_hex(&tree->object.oid)); } b->object.flags |= NOT_USER_GIVEN; - process_blob(ctx, b, base, entry.path, referred_objs); + process_blob(ctx, b, base, entry.path, referred_buf); } } + free(referred_buf); } static void process_tree(struct traversal_context *ctx, diff --git a/object.c b/object.c index f86b52c4d6..895068cbc2 100644 --- a/object.c +++ b/object.c @@ -334,6 +334,7 @@ void add_object_array_with_path_and_referred_commit(struct object *obj, const ch struct referred_objects *referred_objs; referred_objs = xmalloc(sizeof(struct referred_objects)); referred_objs->commit = referred_commit; + referred_objs->trees = NULL; if (nr >= alloc) { alloc = (alloc + 32) * 2; diff --git a/object.h b/object.h index 4db0ecc3f2..618d674249 100644 --- a/object.h +++ b/object.h @@ -65,6 +65,7 @@ struct object_array { struct referred_objects{ struct commit *commit; + struct object_list *trees; }; #define OBJECT_ARRAY_INIT { 0, 0, NULL } -- 2.31.1.453.g945ddc3a74.dirty