summaryrefslogtreecommitdiff
path: root/ref-filter.c
diff options
context:
space:
mode:
authorJan Klötzke <jan@kloetzke.net>2023-07-01 20:57:02 (GMT)
committerJunio C Hamano <gitster@pobox.com>2023-07-17 21:16:05 (GMT)
commit468887f0f8a0a9e465737c3ad23cb40c8d690f2f (patch)
tree438acebc131ee04b7b2f4047d9cf22d49d0a6818 /ref-filter.c
parent5e238546dc7a232d8998f1cd1ec9d3f4a0add68b (diff)
downloadgit-468887f0f8a0a9e465737c3ad23cb40c8d690f2f.zip
git-468887f0f8a0a9e465737c3ad23cb40c8d690f2f.tar.gz
git-468887f0f8a0a9e465737c3ad23cb40c8d690f2f.tar.bz2
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>
Diffstat (limited to 'ref-filter.c')
-rw-r--r--ref-filter.c16
1 files changed, 7 insertions, 9 deletions
diff --git a/ref-filter.c b/ref-filter.c
index 60919f3..7b17128 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;
}