Reputation: 19916
I need Git command to get/find last tag starting with 'v' to get last versioning commit (I am using tags with v letter at the beginning to tag next application version (example: v0.9.1beta).
Is there any way to do it?
Upvotes: 83
Views: 76139
Reputation: 1324347
While a single pattern --match "v[0-9]*"
is enough here, know that Git 2.13 (Q2 2017) will improve that:
"
git describe
" and "git name-rev
" have been taught to take more than one refname patterns to restrict the set of refs to base their naming output on, and also learned to take negative patterns to name refs not to be used for naming via their "--exclude
" option.
See commit 77d21f2, commit 43f8080, commit 96415b4, commit 290be66, commit 4a68748 (18 Jan 2017) by Jacob Keller (jacob-keller
).
(Merged by Junio C Hamano -- gitster
-- in commit 1b32498, 27 Feb 2017)
You now can have multiple match pattern:
--match <pattern>:
Only consider tags matching the given
glob(7)
pattern, excluding the "refs/tags/" prefix.
This can be used to avoid leaking private tags from the repository.If given multiple times, a list of patterns will be accumulated, and tags matching any of the patterns will be considered.
Use--no-match
to clear and reset the list of patterns.
And you have also an exclude pattern (or several) now!
--exclude <pattern>::
Do not consider tags matching the given
glob(7)
pattern, excluding the "refs/tags/" prefix.This can be used to narrow the tag space and find only tags matching some meaningful criteria.
If given multiple times, a list of patterns will be accumulated and tags matching any of the patterns will be excluded.
When combined with--match
a tag will be considered when it matches at least one--match
pattern and does not match any of the--exclude
patterns.
Use--no-exclude
to clear and reset the list of patterns.
Upvotes: 8
Reputation: 31467
Use the following command:
git describe --tags --match="v[0-9]*" HEAD
It will also modify the version if you did something with the source tree since your last versioned tag.
NOTE: --match
accepts a glob, not a regex, and therefore the command shown may match other tags, e.g. v1234_this_matches_too
.
Upvotes: 107
Reputation: 2250
Something more complex would be along the lines of:
/v[0-9]+(\.[0-9]+).*/
Upvotes: -4
Reputation: 570
Also with git describe you could get the latest tag not just reachable from HEAD with :
git describe --match "v*" --abbrev=0 --tags $(git rev-list --tags --max-count=1)
Upvotes: 16
Reputation: 173
The problem with using git describe
as the other answers do is that git describe
will show you tags that are reachable from HEAD (or the commit you specify.)
Imagine you have 3 tags, v1, v2, and v3. If HEAD is at a point between v2 and v3, git describe
would return v2 rather than v3.
If you actually want the latest tag, first of all you need annotated tags as lightweight tags have no date metadata.
Then this command will do it:
git for-each-ref --sort=-taggerdate --count=1 refs/tags/v*
Upvotes: 17
Reputation: 27403
KARASZI István's answer already explains how to find tags matching a glob, which is usually fine enough. Should you ever need a real RegEx though:
for tag in $(git tag | grep YOURREGEX); do
git describe --tags --long --match="$tag" 2>/dev/null
done | sort -k2 -t"-" | head -n1
--abrev=0
would achieve), append | cut -d"-" -f1
--long
's behaviour of also outputting an exactly matching tag including the -0-hash
part, append | sed -e's/-0-.*$//'
instead.The question's example tag would probably use a Regex ^v\d+\.\d+\.\d+\D*$
(though the \D*$
might be optional).
Upvotes: 8
Reputation: 1421
I use
git tag -l --format "%(objecttype) %(refname:short)" --sort=-version:refname --merged HEAD "v*"
git tag
interprets the pattern as glob. So you cannot specify a full blown regex. Just use a minimal glob (v*) or even no glob at all. You will receive more than only one matching tag in sorted order (highest tag version first) and you will be able to regex the output afterwards.
Upvotes: 0