@@ -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);
@@ -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,
@@ -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;
@@ -65,6 +65,7 @@ struct object_array {
struct referred_objects{
struct commit *commit;
+ struct object_list *trees;
};
#define OBJECT_ARRAY_INIT { 0, 0, NULL }