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>
This commit is contained in:
Jan Klötzke
2023-07-01 22:57:02 +02:00
committed by Junio C Hamano
parent 5e238546dc
commit 468887f0f8
2 changed files with 9 additions and 9 deletions

View File

@ -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;
}

View File

@ -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