How can I get the latest tag name in current branch in Git?
Asked Answered
D

26

703

What's the simplest way to get the most recent tag in Git?

git tag a HEAD
git tag b HEAD^^
git tag c HEAD^
git tag

output:

a
b
c

Should I write a script to get each tag's datetime and compare them?

Ditty answered 10/9, 2009 at 11:43 Comment(1)
latest created tag or latest tag ordered by commit date? Your accepted answer shows the latest created tag. This could be a problem if one decides to alter existig tags ...Mame
R
975

To get the most recent tag (example output afterwards):

git describe --tags --abbrev=0   # 0.1.0-dev

To get the most recent tag, with the number of additional commits on top of the tagged object & more:

git describe --tags              # 0.1.0-dev-93-g1416689

To get the most recent annotated tag:

git describe --abbrev=0
Russell answered 31/8, 2011 at 17:39 Comment(12)
Yep, as the man page for git describe says: --abbrev=<n> [...] An <n> of 0 will suppress long format, only showing the closest tag.Adeliaadelice
This answer (and probably the others) runs into trouble if you have two tags pointing to the same commit. Unless the tags are annotated tags, I think there is no way for git to distinguish which of the two was created earlier.Ware
if I have more than two tag, then this doesn't print them allWort
This is what I was looking for. I wanted a way to see the most recent "version" tag without having to manually look through the list myself. When a git repository uses tags to let you download the most recent stable version, this does the job of getting the most recent "version" tag for that project.Argument
if you want to directly checkout the most recent tag: git checkout $(git describe --abbrev=0 --tags)Argument
Add --always to always create a tag (SHA hash if there is none), otherwise if there is no tag it would spill error messages and exist status 128.Azobenzene
Old thread, and feeling stupid, but git fetch --tags origin && git describe --abbrev=0 --tags does not return the latest tag pulled down by the fetch operation. Why not, I wonder?Lindie
This answer is better than current "accepted", because it gives exact command line to use, not just "look at the documentation"Crawley
--abbrev=0 is needed in both commands to display only the tag name (without subsequent commit count and hash). And to clarify, --tags searches for lightweight tags in addition to annotated tags by default.Haase
If "you wish to not match tags on branches merged in the history of the target commit" use git describe --tags --abbrev=0 --first-parentMike
And to find first tag for specific branch, just append the branch name, like git describe --tags upstream/v5.0.0Latitudinarian
This solution is not working on a repository without any tag.Edmundson
B
528

Will output the tag of the latest tagged commit across all branches

git describe --tags $(git rev-list --tags --max-count=1)
Benally answered 2/11, 2011 at 11:2 Comment(9)
This is the best answer. It actually gets tags across all branches, not just the current branch, like the current "correct" answer does.Chaiken
@michaeltwofish, at the time I didn't know it, I figured it out later and corrected accordingly my answer. Sorry about that.Benally
Notes: This command returns the "newest" tag even this tag is on another branch.Butane
I disagree with the claim that the question is about a particular branch. The title of the question implies that, but the question that is actually asked is "What's the simplest way to get the most recent tag in Git?" I guess it's a meta question if the title is the question or not.Sinecure
Regardless of what the OP was asking for, bless you for this answer. It's exactly what I was looking for, latest tag name across all branches without the hash. Thanks @Benally !Shiest
Even though the question asks for the current branch this helped me in finding the latest tag in the best possible way and Thanks for that!Redbreast
I believe nobody wants to get the latest tag of current branch. Because tag is unique across all branches, getting tag of only a branch just doesn't make sense or help anything at all. This awnser should be marked as accepted answer.Shoestring
If you only want to get the latest tag on main, you can use: git describe --tags $(git rev-list --branches=main --tags --max-count=1)Moorish
This is the answer exactly I was looking for and thank you so much for posting!Legitimatize
Q
507

You could take a look at git describe, which does something close to what you're asking.

Quadrille answered 10/9, 2009 at 11:58 Comment(7)
With --abbrev=0 it should return closest annotated tagLodger
Returns the latest tag in the current branch.Chaiken
To get the latest annotated tag which targets only the current commit in the current branch, use git describe --exact-match --abbrev=0.Jackstraws
git describe --tags and compare com last tag in github release pageMossy
git describe --abbrev=0 --tags --exact-matchGrassgreen
I have created 3 tags i.e. "0.0.123-dev", "0.0.124-dev", "0.0.125-dev". I tried to use "git describe --tags". It only shows "0.0.123-dev" which I expect is "0.0.125-dev"Bunn
git describe --tags --abbrev=0 works for me (git version 2.22.0).Demure
S
61

To get the most recent tag, you can do:

$ git for-each-ref refs/tags --sort=-taggerdate --format='%(refname)' --count=1

Of course, you can change the count argument or the sort field as desired. It appears that you may have meant to ask a slightly different question, but this does answer the question as I interpret it.

Sinecure answered 10/3, 2011 at 14:56 Comment(11)
This is almost exactly what I was looking for (the most recent tag across all branches), but at least with my version of git (1.7.7.6) the tags are produced in the same order for both --sort=-authordate and --sort=authordate.Solly
Aha, because what you actually want is --sort=-taggerdate. For tags, authordate and committerdate are empty (so useless as sort keys).Solly
git for-each-ref refs/tags --sort=-taggerdate --format='%(refname:short)' --count=1 is even better :)Marijuana
Please note that it returns the "newest" tag in terms of the tagged time, may not be the most "recent" tag along the tree. For instance, you can checkout any previous commit and tag that commit. The "newest" tag would be the newly created tag.Pah
This should work even for shallow clones. --format='%(tag) will give you a simple tag too.Sulfatize
And --points-at=$SHA will give you the tag for a commit hash.Sulfatize
This is not for a branch. This is the latest tag in the repo period.Unionize
I think you responded elsewhere... still had the window open. Definitely not saying that you didn't answer the actual question. The Googles will take you here if you're looking for how to get the tag for a branch, and there are SO redirects as well.Unionize
To confine this to just the current branch, add --merged.Hollie
In my case (git version 2.34.0), --sort=-authordate is actually what worked... only our "annotated" tag had a taggerdate.Revivify
Note: if you have many types of tags split by /, you can include the prefix in the query. As pointed above, %(refname:short) is nice as it strips the refs/tags prefix in output. I also wanted to know the time of the tag. My final solution: git for-each-ref refs/tags/build/prod --sort=-taggerdate --format='%(refname:short) -- %(creatordate:relative)' --count=1Counterproof
S
49

How about this?

TAG=$(git describe $(git rev-list --tags --max-count=1))

Technically, won't necessarily get you the latest tag, but the latest commit which is tagged, which may or may not be the thing you're looking for.

Stovall answered 26/11, 2009 at 20:11 Comment(4)
This one doesn't get the latest tag in the current branch but for any branches. Which is great, cause it's exactly what I needed. Thanks Wincent.Latishalatitude
If you need to get tag matching pattern you can use --tags=<pattern> in rev-list. For example, get last version tag git describe --tags $(git rev-list --tags='v[0-9].[0-9]*' --max-count=1)Buchanan
$(git describe --contains $(git rev-parse HEAD))Hysell
Thanks, it worked, but, I had to add --tags git describe --tags $(git rev-list --tags --max-count=1)Trawick
T
37

The problem with describe in CI/CD processes is you can run into the fatal: no tags can describe error.

This will occur because, per git describe --help:

The command finds the most recent tag that is reachable from a commit.

If you want the latest tag in the repo, regardless if the branch you are on can reach the tag, typically because it is not part of the current branch's tree, this command will give you the most recently created tag in the entire repo:

git tag -l --sort=-creatordate | head -n 1

More details and other keys to sort on can be found here: https://git-scm.com/docs/git-for-each-ref#_field_names

Tbilisi answered 9/9, 2021 at 21:38 Comment(4)
This doesn't name seem to work in my case. Using powershell on git version 2.37.2.windows.2. I verified this by changing the sort from: --sort=-creatordate to --sort=creatordate and still got the same result order.Lyndy
I'm on OSX currently using git 2.15.x and likely an older version when I posted this.Tbilisi
Not sure what creatordate means, but committerdate works fine for me too: git tag -l --sort=-committerdate | head -n1.Foursquare
For commit and tag objects, the special creatordate and creator fields will correspond to the appropriate date or name-email-date tuple from the committer or tagger fields depending on the object type. These are intended for working on a mix of annotated and lightweight tags. git-scm.com/docs/git-for-each-ref#_field_namesTbilisi
A
35
git describe --abbrev=0 --tags

If you don't see latest tag, make sure of fetching origin before running that:

git remote update
Afterburner answered 19/10, 2015 at 14:40 Comment(1)
Thank you, simply doing git describe --abbrev=0 as suggested in other answers return v1.0.0 which is not latest local tag, adding --tags however gives the right tag.Shonda
R
34

You can execute: git describe --tags $(git rev-list --tags --max-count=1) talked here: How to get latest tag name?

Rouvin answered 12/7, 2018 at 15:1 Comment(2)
I started with the top/accepted answer and worked my way down. This is the first answer that actually gives me the latest tag (not sure why but plain old git describe ... returns an earlier tag?!)Klute
This is the only one that works for me. Tried some of the --abbrev=0 answers and they cut off part of the tag that I want.Leeward
N
31

I'm not sure why there are no answers to what the question is asking for. i.e. All tags (non-annotated included) and without the suffix:

git describe --tags --abbrev=0
Nicety answered 30/6, 2020 at 3:47 Comment(0)
N
28

"Most recent" could have two meanings in terms of git.

You could mean, "which tag has the creation date latest in time", and most of the answers here are for that question. In terms of your question, you would want to return tag c.

Or you could mean "which tag is the closest in development history to some named branch", usually the branch you are on, HEAD. In your question, this would return tag a.

These might be different of course:

A->B->C->D->E->F (HEAD)
       \     \
        \     X->Y->Z (v0.2)
         P->Q (v0.1)

Imagine the developer tag'ed Z as v0.2 on Monday, and then tag'ed Q as v0.1 on Tuesday. v0.1 is the more recent, but v0.2 is closer in development history to HEAD, in the sense that the path it is on starts at a point closer to HEAD.

I think you usually want this second answer, closer in development history. You can find that out by using git log v0.2..HEAD etc for each tag. This gives you the number of commits on HEAD since the path ending at v0.2 diverged from the path followed by HEAD.

Here's a Python script that does that by iterating through all the tags running this check, and then printing out the tag with fewest commits on HEAD since the tag path diverged:

https://github.com/MacPython/terryfy/blob/master/git-closest-tag

git describe does something slightly different, in that it tracks back from (e.g.) HEAD to find the first tag that is on a path back in the history from HEAD. In git terms, git describe looks for tags that are "reachable" from HEAD. It will therefore not find tags like v0.2 that are not on the path back from HEAD, but a path that diverged from there.

Nonbeliever answered 3/7, 2014 at 15:9 Comment(0)
F
28
git tag --sort=committerdate | tail -1
Fimbriation answered 26/12, 2019 at 14:11 Comment(2)
Please explain how this code snippet will solve the problem, instead of posting code-only answer.Largish
This will show all tags, not ones only for the current branch.Bodi
V
25

git describe --tags

returns the last tag able to be seen by current branch

Viscardi answered 6/6, 2012 at 14:5 Comment(0)
G
19
git tag -l ac* | tail -n1

Get the last tag with prefix "ac". For example, tag named with ac1.0.0, or ac1.0.5. Other tags named 1.0.0, 1.1.0 will be ignored.

git tag -l [0-9].* | tail -n1

Get the last tag, whose first char is 0-9. So, those tags with first char a-z will be ignored.

More info

git tag --help # Help for `git tag`

git tag -l <pattern>

List tags with names that match the given pattern (or all if no pattern is given). Running "git tag" without arguments also lists all tags. The pattern is a shell wildcard (i.e., matched using fnmatch(3)). Multiple patterns may be given; if any of them matches, the tag is shown.


tail -n <number> # display the last part of a file
tail -n1 # Display the last item 

Update

With git tag --help, about the sort argument. It will use lexicorgraphic order by default, if tag.sort property doesn't exist.

Sort order defaults to the value configured for the tag.sort variable if it exists, or lexicographic order otherwise. See git-config(1).

After google, someone said git 2.8.0 support following syntax.

git tag --sort=committerdate
Glossectomy answered 25/2, 2016 at 8:23 Comment(2)
its not wok for me, last tag is 2.11.174 but this print 2.11.99 because sort in not as versioningLavellelaven
git tag --sort=taggerdate -l ac* | tail -n1 may handle cases such as ac3.9, ac3.10 betterWilinski
A
17
git log --tags --no-walk --pretty="format:%d" | sed 2q | sed 's/[()]//g' | sed s/,[^,]*$// | sed  's ......  '

IF YOU NEED MORE THAN ONE LAST TAG

(git describe --tags sometimes gives wrong hashes, i dont know why, but for me --max-count 2 doesnt work)

this is how you can get list with latest 2 tag names in reverse chronological order, works perfectly on git 1.8.4. For earlier versions of git(like 1.7.*), there is no "tag: " string in output - just delete last sed call

If you want more than 2 latest tags - change this "sed 2q" to "sed 5q" or whatever you need

Then you can easily parse every tag name to variable or so.

Av answered 24/9, 2013 at 15:34 Comment(2)
this is really helpful, many developers will try to automate release process by rolling back to previous tag if deployment breaks. Awesome stuff!!!Urbas
To take this further: git log --tags --no-walk --pretty="format:%D" | sed -nr '5q;s;^.*(tag: )([^,]*).*;\2;p' where in %D excludes the surrounding () chars, and the seds starting 5q leaves 4 lines before 5, then prints out all characters between 'tag: ` and the first ','. So... assuming no commas are used inside the tag, this works perfectly.Pinprick
P
17

What is wrong with all suggestions (except Matthew Brett explanation, up to date of this answer post)?

Just run any command supplied by other on jQuery Git history when you at different point of history and check result with visual tagging history representation (I did that is why you see this post):

$ git log --graph --all --decorate --oneline --simplify-by-decoration

Todays many project perform releases (and so tagging) in separate branch from mainline.

There are strong reason for this. Just look to any well established JS/CSS projects. For user conventions they carry binary/minified release files in DVCS. Naturally as project maintainer you don't want to garbage your mainline diff history with useless binary blobs and perform commit of build artifacts out of mainline.

Because Git uses DAG and not linear history - it is hard to define distance metric so we can say - oh that rev is most nearest to my HEAD!

I start my own journey in (look inside, I didn't copy fancy proof images to this long post):

What is nearest tag in the past with respect to branching in Git?

Currently I have 4 reasonable definition of distance between tag and revision with decreasing of usefulness:

  • length of shortest path from HEAD to merge base with tag
  • date of merge base between HEAD and tag
  • number of revs that reachable from HEAD but not reachable from tag
  • date of tag regardless merge base

I don't know how to calculate length of shortest path.

Script that sort tags according to date of merge base between HEAD and tag:

$ git tag \
     | while read t; do \
         b=`git merge-base HEAD $t`; \
         echo `git log -n 1 $b --format=%ai` $t; \
       done | sort

It usable on most of projects.

Script that sort tags according to number of revs that reachable from HEAD but not reachable from tag:

$ git tag \
    | while read t; do echo `git rev-list --count $t..HEAD` $t; done \
    | sort -n

If your project history have strange dates on commits (because of rebases or another history rewriting or some moron forget to replace BIOS battery or other magics that you do on history) use above script.

For last option (date of tag regardless merge base) to get list of tags sorted by date use:

$ git log --tags --simplify-by-decoration --pretty="format:%ci %d" | sort -r

To get known current revision date use:

$ git log --max-count=1

Note that git describe --tags have usage on its own cases but not for finding human expected nearest tag in project history.

NOTE You can use above recipes on any revision, just replace HEAD with what you want!

Photosynthesis answered 12/12, 2015 at 11:16 Comment(0)
R
5

The following works for me in case you need last two tags (for example, in order to generate change log between current tag and the previous tag). I've tested it only in situation where the latest tag was the HEAD.

PreviousAndCurrentGitTag=`git describe --tags \`git rev-list --tags --abbrev=0 --max-count=2\` --abbrev=0`
PreviousGitTag=`echo $PreviousAndCurrentGitTag | cut -f 2 -d ' '`
CurrentGitTag=`echo $PreviousAndCurrentGitTag | cut -f 1 -d ' '`

GitLog=`git log ${PreviousGitTag}..${CurrentGitTag} --pretty=oneline | sed "s_.\{41\}\(.*\)_; \1_"`

It suits my needs, but as I'm no git wizard, I'm sure it could be further improved. I also suspect it will break in case the commit history moves forward. I'm just sharing in case it helps someone.

Regine answered 22/1, 2013 at 17:10 Comment(0)
M
5

If you want to find the last tag that was applied on a specific branch you can try the following:

git describe --tag $(git rev-parse --verify refs/remotes/origin/"branch_name")
Martinamartindale answered 27/4, 2018 at 15:56 Comment(0)
F
5

If you need a one liner which gets the latest tag name (by tag date) on the current branch:

git for-each-ref refs/tags --sort=-taggerdate --format=%(refname:short) --count=1 --points-at=HEAD

We use this to set the version number in the setup.

Output example:

v1.0.0

Works on Windows, too.

Foramen answered 31/7, 2019 at 9:5 Comment(3)
On Linux (Debian Stretch) I get -bash: syntax error near unexpected token '('Klute
If I wrap that part in quotes (i.e. --format="%(refname:short)") and skip the --points-at=HEAD it works. With that last switch it returns nothing, I guess because my HEAD isn't tagged?Klute
@JeremyDavis, yes I think that's because your HEAD is not tagged.Foramen
M
4

My first thought is you could use git rev-list HEAD, which lists all the revs in reverse chronological order, in combination with git tag --contains. When you find a ref where git tag --contains produces a nonempty list, you have found the most recent tag(s).

Musca answered 10/9, 2009 at 12:3 Comment(0)
S
3
git tag --sort=-refname | awk 'match($0, /^[0-9]+\.[0-9]+\.[0-9]+$/)' | head -n 1 

This one gets the latest tag across all branches that matches Semantic Versioning.

Shoestring answered 3/9, 2020 at 10:29 Comment(1)
but only if they have exactly three segments, and also does not handle ordering correctly... 9.9.9 will be returned as later than 10.1.1Gladwin
C
1

This is an old thread, but it seems a lot of people are missing the simplest, easiest, and most correct answer to OP's question: to get the latest tag for the current branch, you use git describe HEAD. Done.

Edit: you can also supply any valid refname, even remotes; i.e., git describe origin/master will tell you the latest tag that can be reached from origin/master.

Crespo answered 10/3, 2016 at 21:46 Comment(3)
Nothing guarantees that "the most recent tag" is handled by any branch. The two working solutions are the for-each-ref command (https://mcmap.net/q/13237/-how-can-i-get-the-latest-tag-name-in-current-branch-in-git) and the combination of rev-list and describe (https://mcmap.net/q/13237/-how-can-i-get-the-latest-tag-name-in-current-branch-in-git)Sollars
This does not get the most recent tag for me.Twi
git describe branchname --tags does work for me to get latest tag on branch (git version 2.12.2)Norri
H
1

For the question as asked,

How to get the latest tag name in the current branch

you want

git log --first-parent --pretty=%d | grep -m1 tag:

--first-parent tells git log not to detail any merged histories, --pretty=%d says to show only the decorations i.e. local names for any commits. grep -m1 says "match just one", so you get just the most-recent tag.

Hollie answered 26/2, 2018 at 17:20 Comment(0)
O
0

To get the latest tag only on the current branch/tag name that prefixes with current branch, I had to execute the following

BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags --abbrev=0 $BRANCH^ | grep $BRANCH

Branch master:

git checkout master

BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags 
--abbrev=0 $BRANCH^ | grep $BRANCH

master-1448

Branch custom:

git checkout 9.4

BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags 
--abbrev=0 $BRANCH^ | grep $BRANCH

9.4-6

And my final need to increment and get the tag +1 for next tagging.

BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags  --abbrev=0 $BRANCH^ | grep $BRANCH | awk -F- '{print $NF}'
Orfield answered 16/2, 2018 at 6:17 Comment(0)
C
0

if your tags are sortable:

git tag --merged $YOUR_BRANCH_NAME | grep "prefix/" | sort | tail -n 1
Chiffon answered 17/5, 2018 at 17:21 Comment(0)
L
0

Not much mention of unannotated tags vs annotated ones here. 'describe' works on annotated tags and ignores unannotated ones.

This is ugly but does the job requested and it will not find any tags on other branches (and not on the one specified in the command: master in the example below)

The filtering should prob be optimized (consolidated), but again, this seems to the the job.

git log  --decorate --tags master |grep '^commit'|grep 'tag:.*)$'|awk '{print $NF}'|sed 's/)$//'|head -n 1

Critiques welcome as I am going now to put this to use :)

Latini answered 29/4, 2020 at 5:4 Comment(0)
B
0

I'm using this bash oneline command to get either the latest tag, either the branch name :

git name-rev --tags --name-only HEAD | cut -d '^' -f 1 | grep -v 'undefined' || git rev-parse --abbrev-ref HEAD

This helps me to set the version of my app.

Binnie answered 8/2 at 16:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.