-
-
Save rponte/fdc0724dd984088606b0 to your computer and use it in GitHub Desktop.
# The command finds the most recent tag that is reachable from a commit. | |
# If the tag points to the commit, then only the tag is shown. | |
# Otherwise, it suffixes the tag name with the number of additional commits on top of the tagged object | |
# and the abbreviated object name of the most recent commit. | |
git describe | |
# With --abbrev set to 0, the command can be used to find the closest tagname without any suffix: | |
git describe --abbrev=0 | |
# other examples | |
git describe --abbrev=0 --tags # gets tag from current branch | |
git describe --tags `git rev-list --tags --max-count=1` # gets tags across all branches, not just the current branch | |
For the latest tag on remote I'm doing this:
$ git ls-remote --tags --sort=committerdate | grep -o 'v.*' | sort -r
v1.2.3
v1.2.2
v1.2.1
v1.2.0
v1.1.0
Or, what I wanted, just the single latest one:
$ git ls-remote --tags --sort=committerdate | grep -o 'v.*' | sort -r | head -1
v1.2.3
Faced with problem after using taggerdate
and old git version on CI:
git tag --list "RC;*" --sort=taggerdate | tail -1
error: unsupported sort specification ‘taggerdate’
Found a better way to do it (git describe
and --abbrev=0
argument):
git describe --abbrev=0
git describe --abbrev=0 --match "RC;*"
You can find a same example on https://git-scm.com/docs/git-describe page:
The difference is, that git will take the latest tag for this branch (not for all branches).
A similar approach uses lerna for getting the last tag:
https://github.com/lerna/lerna/blob/f2c3a92fe41b6fdc5d11269f0f2c3e27761b4c85/utils/collect-updates/collect-updates.js#L31
https://github.com/lerna/lerna/blob/f2c3a92fe41b6fdc5d11269f0f2c3e27761b4c85/utils/describe-ref/lib/describe-ref.js#L36
In my case (Git v2.25
), the command git describe --tags $(git rev-list --tags --max-count=1)
returns the latest tag.
What's wrong with a simple git tag -l | tail -1
?
It's sorted alphabetically...
+1 to @joseluisq. Thx man!
Just in case anyone is looking for how to update package.json's version with the latest tag:
let fs = require('fs');
const { exec, execSync } = require('child_process');
if (fs.existsSync('./package.json')) {
var package = require('./package.json');
let currentVersion = package.version;
exec('git tag --sort=committerdate | tail -1', (error, stdout) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
let newVersion = stdout.trim();
package.version = newVersion;
fs.writeFileSync('./package.json', JSON.stringify(package, null, 2));
execSync("git commit -am 'Bump version '" + newVersion);
console.log('Version updated', currentVersion, '=>', newVersion);
});
}
Not working with gitlab, got the usage information.
$ git rev-list --tags --max-count=1
usage: git rev-list [OPTION] <commit-id>... [ -- paths... ]
limiting output:
--max-count=<n>
--max-age=<epoch>
--min-age=<epoch>
--sparse
--no-merges
--min-parents=<n>
--no-min-parents
--max-parents=<n>
--no-max-parents
--remove-empty
--all
--branches
--tags
--remotes
--stdin
--quiet
ordering output:
--topo-order
--date-order
--reverse
formatting output:
--parents
--children
--objects | --objects-edge
--unpacked
--header | --pretty
--abbrev=<n> | --no-abbrev
--abbrev-commit
--left-right
special purpose:
--bisect
--bisect-vars
--bisect-all
Maybe someone will tell me how to get the last tag, or if there are no tags in the branch - the initial commit?
I would like to know how the last tag that was tagged before a specific tag. Meaning lets say I have.
2.0.0
1.5.10
1.5.8
1.0.1
I like to say git --last-tag-b4="1.5.10"
and it should give me 1.5.8
. When 1.5.9 was never created or deleted.
@cawa-93 why not just git tag | sort -V | tail -1
? i.e. Sort tags by version and just take the last one (tail -1
). If that's empty, then git tag
returned nothing.
@nextgenthemes The best (hacky) way I can think of quickly is to use version sort and then use grep
to to find an exact match for the version you know already exists (a possible shortcoming if that exact version you're looking for isn't already present).
# 1. Pull out tags
# 2. Use version sort
# 3. Use grep to find the known version, ensuring we also output the line before
# 4. Just take the first line (the line before the match)
git tag | sort -V | grep -B 1 1.5.8 | head -1
Alternative, you could probably use awk
to use a comparison operator (e.g. awk '$1 < NUMBER { print }'
) but I don't know how to do that when the number has multiple dots in it, nor in a way that would be version safe... 😞
@patricknelson Thanks. I was thinking about some pipe thing. This actually reads and works quite nice. Not sure why I am obsessing trying to do it with more git and less gnu right now. Tell me to stop ;)
One could also do, without using git
: curl -s GET https://api.github.com/repos/aws/aws-cli/tags | jq -r '.[].name' | head -n1
One could also do, without using
git
:curl -s GET https://api.github.com/repos/aws/aws-cli/tags | jq -r '.[].name' | head -n1
add per_page params curl -s GET https://api.github.com/repos/cloudreve/Cloudreve/tags\?per_page\=1 | jq -r '.[].name'
Ran into an issue where we accidentally made two tags on the same commit, in that case this method returns the first tag it encounters, which is the earliest tag, not the latest.
You can get the most recent commit by doing git tag --sort=committerdate | tail -1
The commit date sort way is unreliable, because you don't know if someone create a wrong tag.
Using:
git describe --tags
git rev-list --tags --max-count=1
returns me the last tag with a commit.
but if I create a new tag from an older commit (without a new commit), it will return the wrong tag: the last tag with a commit!
Using:
git tag --sort=committerdate | tail -1
returns me a tag created 1 year ago, I dont know why...
My real last tag:
can someone help me to return the last tag created?
@MarcusPetri found this on StackOverflow: https://stackoverflow.com/a/6270112/899075
git for-each-ref --sort=creatordate --format '%(refname) %(creatordate)' refs/tags
But are you interested in when the tag itself was actually created, or, are you really just interested in seeing the semantically largest tag number (see number sorting below)? The reason I ask is because it's technically possible for you to currently be on v2 but then at a later date create the tag v1.1 (which is obviously smaller) well after both v1 and v2 already existed. That command would sort it as v1, v2, v1.1 instead of the semantic ordering of v1, v1.1, v2 and etc.
Example of naïve sort vs. version sorting:
# Naïve sort
$ sort test/test.txt
0
1.01
10.1
2
vs.
# Version sort
$ sort -V test/test.txt
0
1.01
2
10.1
@MarcusPetri found this on StackOverflow: https://stackoverflow.com/a/6270112/899075
git for-each-ref --sort=creatordate --format '%(refname) %(creatordate)' refs/tags
But are you interested in when the tag itself was actually created, or, are you really just interested in seeing the semantically largest tag number (see number sorting below)? The reason I ask is because it's technically possible for you to currently be on v2 but then at a later date create the tag v1.1 (which is obviously smaller) well after both v1 and v2 already existed. That command would sort it as v1, v2, v1.1 instead of the semantic ordering of v1, v1.1, v2 and etc.
Example of naïve sort vs. version sorting:
# Naïve sort $ sort test/test.txt 0 1.01 10.1 2
vs.
# Version sort $ sort -V test/test.txt 0 1.01 2 10.1
Thanks for the answer.
I just really need the last tag created, I don't care if it has v1, v2...
git tag | sort -g | tail -1
Get the latest tags filtered by branch in descending order, this one looks for latest tags in desc order from develop branch:
git tag --merged develop --sort=committerdate | sort -V desc
git ls-remote --tags --sort=committerdate
important: (from https://git-scm.com/docs/git-ls-remote.html)
_but be aware keys like committerdate that require access to the objects themselves will not work for refs whose objects have not yet been fetched from the remote, and will give a missing object error.
I get this for example on:
git ls-remote --tags --sort=committerdate "https://github.com/box/box-java-sdk"
git ls-remote --tags --sort=committerdate "https://github.com/derailed/k9s"
Get:
tilo@mypc:/mnt/c/GHreps$ git ls-remote --tags --sort=committerdate "https://github.com/derailed/k9s"
fatal: missing object 25b364dd96ae53e70b9639a20732647fd4bb23a7 for refs/tags/0.1.0
tilo@mypc:/mnt/c/GHreps$ git ls-remote --tags --sort=committerdate "https://github.com/box/box-java-sdk"
fatal: missing object 9a8b39475952def867a5b68ab92e7cd45bb3d8e0 for refs/tags/v0.1
If the remote is GitHub and there's an associated release for the tag, why not just use the GitHub API?
$ tag="$(curl -s https://api.github.com/repos/box/box-java-sdk/releases/latest | jq -r '.tag_name')"
$ echo $tag
v4.0.1
Just deleted a stupid long ass comment. Just want to warn about git tag --sort=committerdate
it does not work correctly with the tag command for whatever reason. But this does work.
git for-each-ref --sort=creatordate --format '%(refname) %(creatordate)' refs/tags
COMPLETELY different result that makes no sense to me git tag --sort=committerdate
However git tag --sort=taggerdate
is basically what I always looked for, what should be the default output for git-tag
IMG. I also hate how it paginates the output with less
or whatever by default.
Again, be warned about committerdate
! There is somebody above that had issue as well I think because of this. Even if my commit of things I tagged days or maybe even a week later. I makes absolutely no sense to me WTF this produces. Maybe my memory is just bad and it all makes sense, well probably actually. I think to much about this shit.
@eggbean I like that idea, but it hits an auth wall for private/enterprise repos
@arderyp There are a few different ways to authenticate. Have you tried the gh
cli tool?
Thanks! :)
If the remote is GitHub and there's an associated release for the tag, why not just use the GitHub API?
$ tag="$(curl -s https://api.github.com/repos/box/box-java-sdk/releases/latest | jq -r '.tag_name')" $ echo $tag v4.0.1
@eggbean THANK YOU! This is the perfect solution!
All the other methods mentioned earlier were fetching the most recently created tag, NOT the latest release tag!
@fykaa No problem. I have a lot of GitHub Actions where I was using the GitHub API a lot to retrieve binaries. Maybe you will find them useful to look at as I was using regex to get the latest version.
https://github.com/eggbean/.dotfiles/tree/master/.github/workflows
Yes or the
creatordate
, thecommitterdate
doesn't work for me.And don't forget that you can add
-
(e.g.--sort=-taggerdate
) before to sort it as newer -> older