diff options
| author | Jan Klötzke <jan@kloetzke.net> | 2023-07-01 22:57:02 +0200 |
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2023-07-17 14:16:05 -0700 |
| commit | 468887f0f8a0a9e465737c3ad23cb40c8d690f2f (patch) | |
| tree | 438acebc131ee04b7b2f4047d9cf22d49d0a6818 | |
| parent | 5e238546dc7a232d8998f1cd1ec9d3f4a0add68b (diff) | |
| download | git-468887f0f8a0a9e465737c3ad23cb40c8d690f2f.tar.xz | |
ref-filter: handle nested tags in --points-at option
Tags are dereferenced until reaching a different object type to handle
nested tags, e.g. on checkout. In contrast, "git tag --points-at=..."
fails to list such nested tags because only one level of indirection is
obtained in filter_refs(). Implement the recursive dereferencing for the
"--points-at" option when filtering refs to unify the behaviour.
Signed-off-by: Jan Klötzke <jan@kloetzke.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
| -rw-r--r-- | ref-filter.c | 16 | ||||
| -rwxr-xr-x | t/t6302-for-each-ref-filter.sh | 2 |
2 files changed, 9 insertions, 9 deletions
diff --git a/ref-filter.c b/ref-filter.c index 60919f375f..7b17128bef 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -2332,10 +2332,7 @@ static int for_each_fullref_in_pattern(struct ref_filter *filter, * of oids. If the given ref is a tag, check if the given tag points * at one of the oids in the given oid array. * NEEDSWORK: - * 1. Only a single level of indirection is obtained, we might want to - * change this to account for multiple levels (e.g. annotated tags - * pointing to annotated tags pointing to a commit.) - * 2. As the refs are cached we might know what refname peels to without + * As the refs are cached we might know what refname peels to without * the need to parse the object via parse_object(). peel_ref() might be a * more efficient alternative to obtain the pointee. */ @@ -2343,18 +2340,19 @@ static const struct object_id *match_points_at(struct oid_array *points_at, const struct object_id *oid, const char *refname) { - const struct object_id *tagged_oid = NULL; struct object *obj; if (oid_array_lookup(points_at, oid) >= 0) return oid; obj = parse_object(the_repository, oid); + while (obj && obj->type == OBJ_TAG) { + oid = get_tagged_oid((struct tag *)obj); + if (oid_array_lookup(points_at, oid) >= 0) + return oid; + obj = parse_object(the_repository, oid); + } if (!obj) die(_("malformed object at '%s'"), refname); - if (obj->type == OBJ_TAG) - tagged_oid = get_tagged_oid((struct tag *)obj); - if (tagged_oid && oid_array_lookup(points_at, tagged_oid) >= 0) - return tagged_oid; return NULL; } diff --git a/t/t6302-for-each-ref-filter.sh b/t/t6302-for-each-ref-filter.sh index 1ce5f490e9..af223e44d6 100755 --- a/t/t6302-for-each-ref-filter.sh +++ b/t/t6302-for-each-ref-filter.sh @@ -45,6 +45,8 @@ test_expect_success 'check signed tags with --points-at' ' sed -e "s/Z$//" >expect <<-\EOF && refs/heads/side Z refs/tags/annotated-tag four + refs/tags/doubly-annotated-tag An annotated tag + refs/tags/doubly-signed-tag A signed tag refs/tags/four Z refs/tags/signed-tag four EOF |
