summaryrefslogtreecommitdiff
path: root/ref-filter.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2023-07-25 19:05:24 (GMT)
committerJunio C Hamano <gitster@pobox.com>2023-07-25 19:05:24 (GMT)
commit5929e66755acc797b2612d8d6d6b6fd6e7759169 (patch)
treebdf6fe770fdd951a48db8e571904fa963cc30d71 /ref-filter.c
parent02f50d0d1901759d9e7aec1367902cab09db63a6 (diff)
parentd9e00621591549cd2d9989d290a7e0c63eadd03b (diff)
downloadgit-5929e66755acc797b2612d8d6d6b6fd6e7759169.zip
git-5929e66755acc797b2612d8d6d6b6fd6e7759169.tar.gz
git-5929e66755acc797b2612d8d6d6b6fd6e7759169.tar.bz2
Merge branch 'jk/nested-points-at'
"git tag --list --points-at X" showed tags that directly refers to object X, but did not list a tag that points at such a tag, which has been corrected. * jk/nested-points-at: ref-filter: simplify return type of match_points_at ref-filter: avoid parsing non-tags in match_points_at() ref-filter: avoid parsing tagged objects in match_points_at() ref-filter: handle nested tags in --points-at option
Diffstat (limited to 'ref-filter.c')
-rw-r--r--ref-filter.c40
1 files changed, 24 insertions, 16 deletions
diff --git a/ref-filter.c b/ref-filter.c
index 0f3df13..f0a8e55 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -2344,32 +2344,40 @@ static int for_each_fullref_in_pattern(struct ref_filter *filter,
/*
* Given a ref (oid, refname), check if the ref belongs to the array
* 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.
+ * at one of the oids in the given oid array. Returns non-zero if a
+ * match is found.
+ *
* 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.
*/
-static const struct object_id *match_points_at(struct oid_array *points_at,
- const struct object_id *oid,
- const char *refname)
+static int 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);
+ return 1;
+ obj = parse_object_with_flags(the_repository, oid,
+ PARSE_OBJECT_SKIP_HASH_CHECK);
+ while (obj && obj->type == OBJ_TAG) {
+ struct tag *tag = (struct tag *)obj;
+
+ if (parse_tag(tag) < 0) {
+ obj = NULL;
+ break;
+ }
+
+ if (oid_array_lookup(points_at, get_tagged_oid(tag)) >= 0)
+ return 1;
+
+ obj = tag->tagged;
+ }
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;
+ return 0;
}
/*