If you are using git tag --points-at HEAD
, make sure to use Git 2.42 (Q3 2023).
"git tag --list --points-at X
"(man) showed tags that directly refers to object X
, but did not list a tag that points at such a tag, which has been corrected with Git 2.42 (Q3 2023).
See commit d9e0062, commit 870eb53, commit b9584c5 (02 Jul 2023) by Jeff King (peff
).
See commit 468887f (01 Jul 2023) by Jan Klötzke (jkloetzke
).
(Merged by Junio C Hamano -- gitster
-- in commit 5929e66, 25 Jul 2023)
ref-filter
: handle nested tags in --points-at option
Signed-off-by: Jan Klötzke
Tags are dereferenced until reaching a different object type to handle nested tags, e.g. on checkout.
In contrast, "git tag --points-at=...
"(man) 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.
That will list nested tag, and that will do it faster:
ref-filter
: avoid parsing tagged objects in match_points_at()
Signed-off-by: Jeff King
When we peel tags to check if they match a --points-at
oid, we recursively parse the tagged object to see if it is also a tag.
But since the tag itself tells us the type of the object it points to (and even gives us the appropriate object struct via its "tagged" member), we can use that directly.
We do still have to make sure to call parse_tag()
before looking at each tag.
This is redundant for the outermost tag (since we did call parse_object()
to find its type), but that's OK; parse_tag()
is smart enough to make this a noop when the tag has already been parsed.
In my clone of linux.git, with 782 tags (and only 3 non-tags), this yields a significant speedup (bringing us back where we were before the commit before this one started recursively dereferencing tags):
Benchmark 1: ./git.old for-each-ref --points-at=HEAD --format="%(refname)"
Time (mean ± σ): 20.3 ms ± 0.5 ms [User: 11.1 ms, System: 9.1 ms]
Range (min … max): 19.6 ms … 21.5 ms 141 runs
Benchmark 2: ./git.new for-each-ref --points-at=HEAD --format="%(refname)"
Time (mean ± σ): 11.4 ms ± 0.2 ms [User: 6.3 ms, System: 5.0 ms]
Range (min … max): 11.0 ms … 12.2 ms 250 runs
Summary
'./git.new for-each-ref --points-at=HEAD --format="%(refname)"' ran
1.79 ± 0.05 times faster than './git.old for-each-ref --points-at=HEAD --format="%(refname)"'