Reputation: 36513
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?
Upvotes: 738
Views: 527359
Reputation: 1223
In addition to all above answers, you could also add the branch that you want to get the tags from and also a matcher to search for specific tags names.
git describe --tags --abbrev=0 --match=*build-* # search for tags with build as prefix
#With branch name
git describe main --tags --abbrev=0 --match=*build-* # search for tags with build as prefix
Upvotes: 1
Reputation: 22023
When trying to solve this in my team, when we had several tags on the HEAD of our main branch (used to get the release version of our product, we just did a simple:
git tag -l --contains HEAD | tail -n1
To avoid extra tags that may be introduced by CI/CD during release, it's easy to add a grep before the tail, but this retrieves the last tag added to the commit on top of the current branch.
Upvotes: 0
Reputation: 1
Below is the command that seems to work to achieve the recently tag created from the current commit (not comfortable yet with the glob pattern):
git describe --tags --match '*.*.*' --match '*.*.*-*' --match '*.*.*-rc.*' --first-parent --abbrev=0
Upvotes: 0
Reputation: 1450
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.
Upvotes: 5
Reputation: 199
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.
Upvotes: 0
Reputation: 5391
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
Upvotes: 41
Reputation: 735
git describe --abbrev=0 --tags
If you don't see latest tag, make sure of fetching origin before running that:
git remote update
Upvotes: 37
Reputation: 2711
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
Upvotes: 32
Reputation: 10425
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
Upvotes: 1024
Reputation: 9439
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.
Upvotes: 3
Reputation: 3721
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 :)
Upvotes: 0
Reputation: 1489
You can execute: git describe --tags $(git rev-list --tags --max-count=1)
talked here: How to get latest tag name?
Upvotes: 34
Reputation: 4887
if your tags are sortable:
git tag --merged $YOUR_BRANCH_NAME | grep "prefix/" | sort | tail -n 1
Upvotes: 0
Reputation: 514
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")
Upvotes: 5
Reputation: 60487
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.
Upvotes: 1
Reputation: 10375
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}'
Upvotes: 0
Reputation: 18418
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.
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
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
Upvotes: 20
Reputation: 528
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.
Upvotes: 1
Reputation: 48893
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:
HEAD
to merge base with tagHEAD
and tagI 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!
Upvotes: 17
Reputation: 7806
Will output the tag of the latest tagged commit across all branches
git describe --tags $(git rev-list --tags --max-count=1)
Upvotes: 546
Reputation: 925
"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.
Upvotes: 29
Reputation: 507
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.
Upvotes: 49
Reputation: 203
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.
Upvotes: 17
Reputation: 212534
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.
Upvotes: 62
Reputation: 970
git describe --tags
returns the last tag able to be seen by current branch
Upvotes: 25
Reputation: 9679
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.
Upvotes: 5
Reputation: 994301
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).
Upvotes: 4
Reputation: 42154
You could take a look at git describe
, which does something close to what you're asking.
Upvotes: 508