How to tell which commit a tag points to in Git?
GitGit TagGit Problem Overview
I have a bunch of unannotated tags in the repository and I want to work out which commit they point to. Is there a command that that will just list the tags and their commit SHAs? Checking out the tag and looking at the HEAD seems a bit too laborious to me.
Update
I realized after I went through the responses that what I actually wanted was to simply look at the history leading up to the tag, for which git log <tagname>
is sufficient.
The answer that is marked as answer is useful for getting a list of tags and their commits, which is what I asked. With a bit of shell hackery I'm sure it's possible to transform those into SHA+Commit message.
Git Solutions
Solution 1 - Git
One way to do this would be with git rev-list
. The following will output the commit to which a tag points:
$ git rev-list -n 1 $TAG
NOTE This works for both Annotated and Unannotated tags
You could add it as an alias in ~/.gitconfig
if you use it a lot:
[alias]
tagcommit = rev-list -n 1
And then call it with:
$ git tagcommit $TAG
Possible pitfall: if you have a local checkout or a branch of the same tag name, this solution might get you "warning: refname 'myTag' is ambiguous". In that case, try increasing specificity, e.g.:
$ git rev-list -n 1 tags/$TAG
Solution 2 - Git
WARNING This only works for Unannotated tags Therefore it is safer to use the accepted answer which works in the general case https://stackoverflow.com/a/1862542/1586965
git show-ref --tags
For example, git show-ref --abbrev=7 --tags
will show you something like the following:
f727215 refs/tags/v2.16.0
56072ac refs/tags/v2.17.0
b670805 refs/tags/v2.17.1
250ed01 refs/tags/v2.17.2
Solution 3 - Git
Just use git show <tag>
However, it also dumps commit diffs. To omit those diffs, use git log -1 <tag>
. (Thanks to @DolphinDream and @demisx !)
Solution 4 - Git
From Igor Zevaka:
Summary
Since there are about 4 almost equally acceptable yet different answers I will summarise all the different ways to skin a tag.
-
git rev-list -1 $TAG
(answer).git rev-list
outputs the commits that lead up to the$TAG
similar togit log
but only showing the SHA1 of the commit. The-1
limits the output to the commit it points at. -
git show-ref --tags
(answer) will show all tags (local and fetched from remote) and their SHA1s. -
git show-ref $TAG
(answer) will show the tag and its path along with the SHA1. -
git rev-parse $TAG
(answer) will show the SHA1 of an unannotated tag. -
git rev-parse --verify $TAG^{commit}
(answer) will show a SHA1 of both annotated and unannotated tags. On Windows usegit rev-parse --verify %TAG%^^^^{commit}
(four hats). -
cat .git/refs/tags/*
orcat .git/packed-refs
(answer) depending on whether or not the tag is local or fetched from remote.
Solution 5 - Git
For annotated tags, git show-ref TAG
shows the tag's hash, not the hash of the commit it points to.
git show-ref --dereference TAG
shows, additionally, the commit being pointed at with an added ^{}
.
Solution 6 - Git
Use
git rev-parse --verify <tag>^{commit}
(which would return SHA-1 of a commit even for annotated tag).
git show-ref <tag>
would also work if <tag>
is not annotated. And there is always git for-each-ref
(see documentation for details).
Solution 7 - Git
How about this:
git log -1 $TAGNAME
OR
git log -1 origin/$TAGNAME
Solution 8 - Git
In order to get the sha/hash of the commit that a tag refers to (not the sha of the tag):
git rev-list -1 <tag>
Solution 9 - Git
Short post-Git-2 answer
I know this question has been out here for quite a while. And the answer from CB Bailey is 100% correct: git show-ref --tags --abbrev
I like this one better since it uses git tag
:
git tag --list --format '%(refname:short) %(objectname:short)'
Simple. Short.
PS alias it as git taglist
with this command:
git config --global alias.taglist "tag --list --format '%(refname:short) %(objectname:short)'"
Solution 10 - Git
I'd also like to know the "right" way, but in the meantime, you can do this:
git show mytag | head -1
Solution 11 - Git
Even though this is pretty old, I thought I would point out a cool feature I just found for listing tags with commits:
git log --decorate=full
It will show the branches which end/start at a commit, and the tags for commits.
Solution 12 - Git
You could as well get more easy-to-interpret picture of where tags point to using
git log --graph |git name-rev --stdin --tags |less
and then scroll to the tag you're looking for via /
.
More compact view (--pretty=oneline
) plus all heads (-a
) could also help:
git log -a --pretty=oneline --graph |git name-rev --stdin --tags |less
Looks a bit terrifying, but could also be aliased in ~/.gitconfig
if necessary.
~/.gitconfig
[alias]
ls-tags = !git log -a --pretty=oneline --graph |git name-rev --stdin --tags |less
Solution 13 - Git
The --format
option can be used to show both tag hash and the commit hash, and to distinguish between lightweight and annotated tags.
git tag --format="%(color:bold cyan)== %(refname:short) ==%(if)%(object)%(then)%0aTag Hash: %(objectname)%0aTag Date: %(taggerdate:iso-local)%0a Commit: %(object) %0a%0a%(contents)%(else)%0a(lightweight tag)%0a Commit: %(objectname)%(end)%0a"
Gives output similar to:
== b2lightweight ==
(lightweight tag)
Commit: 0450fae4352dbbbf088419757eda32711316a02e
== c3_annotated ==
Tag Hash: 19961d8678a09a319a9d6c398c79f27cc23d610c
Tag Date: 2021-08-06 15:18:48 -0600
Commit: 85be6e80c109ce44d78f0ca0da8e1ec53817b24c
This is my tag message.
It has multiple lines.
Another line.
To define as a git alias, you can edit the global git config with git config --global -e
and add the following:
[alias]
tag-verbose = tag --format='%(color:bold cyan)== %(refname:short) ==%(if)%(object)%(then)%0aTag Hash: %(objectname)%0aTag Date: %(taggerdate:iso-local)%0a Commit: %(object) %0a%0a%(contents)%(else)%0a(lightweight tag)%0a Commit: %(objectname)%(end)%0a'
The alias still allows filtering, e.g.
C:\playground>git tag-verbose -l *b2*
== b2lightweight ==
(lightweight tag)
Commit: 0450fae4352dbbbf088419757eda32711316a02e
For additional information on the --format
options see the "Field Names" section under git help for-each-ref
. (git help tag
states "The format is the same as that of git-for-each-ref")
Solution 14 - Git
This doesn't show the filenames, but at least you get a feel of the repository.
cat .git/refs/tags/*
Each file in that directory contains a commit SHA pointing to a commit.
Solution 15 - Git
From git mailing list, here is the way to get the list of commit hashes for tags with automatic dereferencing for annotated tags:
git for-each-ref --format='%(if)%(*objectname)%(then)%(*objectname)%(else)%(objectname)%(end) %(refname)' refs/tags
Solution 16 - Git
i'd also like to know the right way, but you can always peek either into:
$ cat .git/packed-refs
or:
$ cat .git/refs/tags/*
Solution 17 - Git
This will get you the current SHA1 hash
Abbreviated Commit Hash
git show <tag> --format="%h" --> 42e646e
Commit Hash
git show <tag> --format="%H" --> 42e646ea3483e156c58cf68925545fffaf4fb280
Solution 18 - Git
If you would like to see the details of the tag SOMETAG (tagger, date, etc), the hash of the commit it points to and a bit of info about the commit but without the full diff, try
git show --name-status SOMETAG
Example output:
tag SOMETAG
Tagger: ....
Date: Thu Jan 26 17:40:53 2017 +0100
.... tag message .......
commit 9f00ce27c924c7e972e96be7392918b826a3fad9
Author: .............
Date: Thu Jan 26 17:38:35 2017 +0100
.... commit message .......
..... list of changed files with their change-status (like git log --name-status) .....
Solution 19 - Git
So I have a load of release folders, where those folders may be checked out from one of a few different repos, and may be dev, qa or master branches or may be production releases, checked out from a tag, and the tag may be annotated or not. I have a script that will look at the target folder and get be back an answer in the form
So I found git show-ref --tags
worked initially, except for the annotated tags. However adding -d added a separate entry to the list of tags, one for the tag, the other for the annotation (the annotation commit was identified as
So this is the core of my script, for anyone that wants it:-
REPO=`git --git-dir=${TARGET} remote show origin -n | \
grep "Fetch URL:" | \
sed -E "s/^.*\/(.*)$/\1/" | \
sed "s/.git$//"`
TAG=`git --git-dir=${TARGET} show-ref -d --tags | \
grep \`git --git-dir=${TARGET} show --quiet --format=format:%H HEAD\` | \
cut -d\ -f2 | \
cut -d/ -f3 | \
sed "s/\^{}$//"`
if [ "${TAG}" == "" ] ; then
BRANCH=`git --git-dir=${TARGET} show-ref --heads | \
grep \`git --git-dir=${TARGET} show --quiet --format=format:%H HEAD\` | \
cut -d\ -f2 | \
cut -d/ -f3`
TAG=${BRANCH}
fi
Solution 20 - Git
Can use below, It will give the commit hash
git show -s --format=%H <tag>^{commit}
If abbreviated commit hash required, git show -s --format=%h <tag>^{commit}
Solution 21 - Git
Hacky solution
Parse the .git/packed-refs
and format it as {tag}\t{sha}
sed -n '/ refs\/tags/ { s@\([^ ]*\) refs/tags/\(.*\)@\2\t\1@; p}' .git/packed-refs