This commit supports the use of `uploadpack.excludeobject` to exclude tag objects, both lightweight tag and annotated tag are supported: -If a lightweight tag (such as a commit object) have been configured, the mechanism of exclusion is the same as the commit object (the commit object and all objects it contains will be recusively excluded). -If an annotated tag (created with -a, -s, or -u) have been configured, the annotated tag and all the objects that it contains will be excluded, For an example of the annotated tag: Create an annotated tag from HEAD: git tag -a A -m "tag A description" Output the SHA (<tag_oid>) of tag "A" : git rev-parse A^{object} Dereference <tag_oid>, output the SHA <commit_oid> of commit: git rev-parse A^{} In the above case, when the tag object (<tag_oid>) is configured with `uploadpack.excludeobject` which means <tag_oid>, the dereference commit object (<commit_oid>), and all the objects that <commit_oid> recursively contains (trees, blobs), will be excluded (using a packfile URI instead). Signed-off-by: Teng Long <dyroneteng@xxxxxxxxx> --- builtin/pack-objects.c | 20 ++++++++++++++++++-- list-objects.c | 9 ++++++++- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index d38b24e375..d5e3f2c229 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -1317,9 +1317,11 @@ static int want_object_in_pack(const struct object_id *oid, int want; struct list_head *pos; struct multi_pack_index *m; + struct configured_exclusion *tag_ex; struct configured_exclusion *commit_ex; struct configured_exclusion *tree_ex; struct configured_exclusion *ex; + struct object_list *p; if (!exclude && local && has_loose_object_nonlocal(oid)) return 0; @@ -1355,14 +1357,27 @@ static int want_object_in_pack(const struct object_id *oid, } if (uri_protocols.nr) { + if (referred_objs && referred_objs->tags) { + for (p = referred_objs->tags; p; p = p->next) { + tag_ex = oidmap_get(&configured_exclusions, &p->item->oid); + if (match_packfile_uri_exclusions(tag_ex)) + return 0; + } + } + if (referred_objs && referred_objs->commit) { commit_ex = oidmap_get(&configured_exclusions, &referred_objs->commit->oid); if (match_packfile_uri_exclusions(commit_ex)) return 0; + struct commit *commit = (struct commit*) referred_objs->commit; + for (p = commit->wraps; p; p = p->next) { + tag_ex = oidmap_get(&configured_exclusions, &p->item->oid); + if (match_packfile_uri_exclusions(tag_ex)) + return 0; + } } if (referred_objs && referred_objs->trees) { - struct object_list *p; for (p = referred_objs->trees; p; p = p->next) { tree_ex = oidmap_get(&configured_exclusions, &p->item->oid); if (match_packfile_uri_exclusions(tree_ex)) @@ -3260,7 +3275,8 @@ static void read_object_list_from_stdin(void) static void show_commit(struct commit *commit, void *show_data, void *carry_data) { - add_object_entry(&commit->object.oid, OBJ_COMMIT, NULL, 0, NULL); + struct referred_objects *referred_objs = carry_data; + add_object_entry(&commit->object.oid, OBJ_COMMIT, NULL, 0, referred_objs); commit->object.flags |= OBJECT_ADDED; if (write_bitmap_index) diff --git a/list-objects.c b/list-objects.c index 2e53a01458..52f38c9151 100644 --- a/list-objects.c +++ b/list-objects.c @@ -367,6 +367,7 @@ static void do_traverse(struct traversal_context *ctx) { struct commit *commit; struct strbuf csp; /* callee's scratch pad */ + struct referred_objects *referred_objs; strbuf_init(&csp, PATH_MAX); while ((commit = get_revision(ctx->revs)) != NULL) { @@ -384,7 +385,13 @@ static void do_traverse(struct traversal_context *ctx) die(_("unable to load root tree for commit %s"), oid_to_hex(&commit->object.oid)); } - ctx->show_commit(commit, ctx->show_data, NULL); + referred_objs = xmalloc(sizeof(struct referred_objects)); + referred_objs->commit = NULL; + referred_objs->trees = NULL; + referred_objs->tags = commit->wraps; + + ctx->show_commit(commit, ctx->show_data, referred_objs); + free(referred_objs); if (ctx->revs->tree_blobs_in_commit_order) /* -- 2.31.1.456.gec51e24953