问题
How to get last tag from a (non checked-out) remote repo?
On my local copy I use describe
git describe --abbrev=0 --tags
But I cannot use describe
with remote storage
回答1:
Use git ls-remote --tags <repository>
For example, if we want to know what the latest tag that Git is at we would do
git ls-remote --tags git://github.com/git/git.git
That returns a long list with all the tags in alphabetical order, as shown below (truncated for sanity's sake).
The last line tells us the latest tag is v1.8.0-rc0
.
Keep in mind that tags can be any kind of string so, as pointed out by Christopher Gervais in his answer, git ls-remote
sorts tags alphabetically. Unfortunately git ls-remote
does not have a --sort
option (like, for example git for-each-ref), so your best option is to use native sort.
More recent versions of sort
support the -V
or --version-sort
flag to do a natural sort of (version) numbers within text.
So to sort them naturally, your command would look like this:
git ls-remote --tags git://github.com/git/git.git | sort -t '/' -k 3 -V
Please take a look at (and upvote) Christopher Gervais's answer below if you need more/other grep
ing options.
...
e4dc716b1cfefb0e1bd46c699d4f74009118d001 refs/tags/v1.7.9
828ea97de486c1693d6e4f2c7347acb50235a85d refs/tags/v1.7.9^{}
cc34c0417dfd4e647e41f3d34a032b7164aadea7 refs/tags/v1.7.9-rc0
eac2d83247ea0a265d923518c26873bb12c33778 refs/tags/v1.7.9-rc0^{}
ad2ec9a47a031ebf056444a94bea3750aaa68f63 refs/tags/v1.7.9-rc1
6db5c6e43dccb380ca6e9947777985eb11248c31 refs/tags/v1.7.9-rc1^{}
eab05abaeb51531e11835aaa4c26564a1babebac refs/tags/v1.7.9-rc2
bddcefc6380bd6629f3f12b5ffd856ec436c6abd refs/tags/v1.7.9-rc2^{}
...
5ace0b7af106b44687005085d8c252f8be9da5d3 refs/tags/v1.8.0-rc0
b0ec16b49eb283156e13bbef26466d948e4fd992 refs/tags/v1.8.0-rc0^{}
回答2:
Unfortuntely, git ls-remote --tags
actually lists tags alphabetically (at least as of 1.7.2.5). So, at the time that 1.7.10, 1.7.11 or 1.7.12 were the latest tags, 1.7.9 would have been the last on the list:
git ls-remote --tags git://github.com/git/git.git |grep "1\.7\."
[...]
bf68fe0313c833fa62755176f6e24988ef7cf80f refs/tags/v1.7.9.6
cb2ed324fc917db0b79d7b1f3756575ffa5f70d5 refs/tags/v1.7.9.6^{}
3996bb24c84013ec9ce9fa0980ce61f9ef97be4d refs/tags/v1.7.9.7
d0f1ea6003d97e63110fa7d50bb07f546a909b6e refs/tags/v1.7.9.7^{}
However, we can pipe these results through 'sort' to get closer to the results we're looking for:
git ls-remote --tags git://github.com/git/git.git |grep "1\.7\."| sort -g -k3 -t.
[...]
eab05abaeb51531e11835aaa4c26564a1babebac refs/tags/v1.7.9-rc2
eac2d83247ea0a265d923518c26873bb12c33778 refs/tags/v1.7.9-rc0^{}
f59f511e26b4924b22c6966e79fe4f754bc81dc6 refs/tags/v1.7.9.2
0e2d57fd50f61e668be3180bc8f25991ea88aa8c refs/tags/v1.7.10-rc1^{}
121f71f0da1bc9a4e1e96be2c3e683191a82a354 refs/tags/v1.7.10.4^{}
26e5c5d09334d157bd04f794f16f6e338d50c752 refs/tags/v1.7.10.3^{}
[...]
cffb45719f60d6fc2cc98ead6af88a895c63c9ac refs/tags/v1.7.12.4
d8cf053dacb4f78920c112d10c7be21e4f5a5817 refs/tags/v1.7.12.2^{}
dcd07fb6262fd8bb9f531890df3986a8b719a0b5 refs/tags/v1.7.12-rc0
e15c16de396a1e1f42001b03cb885ce64eb4098e refs/tags/v1.7.12-rc2^{}
While still not correct, it's closer. If we exclude -rc and ^{}, and add an additional sort on the last sub-version number, we can probably get close enough for most needs:
git ls-remote --tags git://github.com/git/git.git |grep "1\.7\."|grep -v -|grep -v {| sort -n -t. -k3 -k4
23ed9debf17263ed6bed478a4d6d86e71342c18a refs/tags/v1.7.11.6
527b331100ddba839cc54bb31c1bcd66acc08321 refs/tags/v1.7.11.7
14d20a75e3d57a872a8c81ae90dcc4c61ddba011 refs/tags/v1.7.12
51993a414a76120fda20d56ba767fa513d9ff440 refs/tags/v1.7.12.1
04043f4d1ae42bddee67d354a2e6fd2464592a1e refs/tags/v1.7.12.2
b38da673be332933b8f3a873ce46ffea08d2ee2c refs/tags/v1.7.12.3
cffb45719f60d6fc2cc98ead6af88a895c63c9ac refs/tags/v1.7.12.4
回答3:
As of Git 2.18 you actually can use the --sort
option, so the up-to-date command would be
git ls-remote --tags --sort="v:refname" git://github.com/git/git.git | tail -n1
To also remove the hash and the dereference marker (^{}
), just throw in some simple sed
git ls-remote --tags --sort="v:refname" git://github.com/git/git.git | tail -n1 | sed 's/.*\///; s/\^{}//'
# outputs something like: v2.18.0
回答4:
This worked for me how to get latest tag from github remote repository
git ls-remote --tags "#{github_repo}" | awk '{print $2}' | grep -v '{}' | awk -F"/" '{print $3}' | sort -n -t. -k1,1 -k2,2 -k3,3 | tail -n 1.chomp
回答5:
TL;DR:
% git -c 'versionsort.suffix=-' ls-remote -t --exit-code --refs --sort=-v:refname \
https://github.com/robert7/nixnote2 'v*' \
| sed -En '1!q;s/^[[:xdigit:]]+[[:space:]]+refs\/tags\/(.+)/\1/gp'
v2.1.0-beta4g
Explanation
Pass --refs
to git ls-remote to get rid of the {}
refs shown in other answers:
$ git ls-remote -t --refs <URL>
This gives output such as:
8f235769a2853c415f811b19cd5effc47cc89433 refs/tags/continuous
24e666ed73486a2ac65f09a1479e91e6ae4a1bbe refs/tags/continuous-develop
7c2cff2c26c1c2ad4b4023a975cd2365751ec97d refs/tags/v2.0
35b69eed46e5b163927c78497983355ff6a5dc6b refs/tags/v2.0-beta10
To get only the tag names, pass through:
sed -E 's/^[[:xdigit:]]+[[:space:]]+refs\/tags\/(.+)/\1/g'
:
$ git ls-remote -t --exit-code --refs https://github.com/robert7/nixnote2.git \
| sed -E 's/^[[:xdigit:]]+[[:space:]]+refs\/tags\/(.+)/\1/g'
continuous
continuous-develop
v2.0
v2.0-beta10
You can then pass the cleaned up list through an appropriate grep
and/or head -n1
(or add to your sed
command if you like keeping your PID numbers low.)
Suggestions:
- Add a pattern at the end of the command line to filter. Eg
'v*'
if all version tags start with av
. - Pass
--exit-code
to ensure a non-0
exit when no matching refs are returned. - Use the
https://
version: it's faster and if you're packaging you don't want to run the risk of being asked for a ssh key. --sort=-v:refname
to sort by version rather than lexographically, and have the largest versions at the top- Use
git -c versionsort.suffix=-
to prevent2.0-rc
coming "after"2.0
回答6:
Here is my one-liner :-)
git ls-remote --tags git://github.com/git/git.git | cut -d/ -f3- | sort -t. -nk1,2 -k3 | awk '/^[^{]*$/{version=$1}END{print version}'
来源:https://stackoverflow.com/questions/10649814/get-last-git-tag-from-a-remote-repo-without-cloning