How do `ls-remote --refs` vs. cloning then `describe --tags` relate?

500 views Asked by At

Listing the most recent tag of a remote repository produces a different answer from cloning that repository and then describing its tags. E.g.

$ ​git ls-remote --refs git://git.kernel.org/pub/scm/git/git.git | tail -1
dcba104ffdcf2f27bc5058d8321e7a6c2fe8f27e    refs/tags/v2.9.5
$ git clone -q git://git.kernel.org/pub/scm/git/git.git gitdir && cd gitdir && git describe --tags
v2.31.1-606-gdf6c4f7

How do these two kinds of values relate to one another? How are they different?

I understand that "tag names are local" and my question may relate to that, but I think I don't understand that phrase's implications. I did try another suggestion to git fetch --tags before calling describe, to no avail.

What I ultimately want to do is to programmatically find the most stable release or tag if they aren't using releases, and check out that version to build it locally.

2

There are 2 answers

0
joanis On BEST ANSWER

TL;DR

I believe what you want is the first token from the output of git describe --tags.

Details

The two commands serve different purposes.

git ls-remote lists the references on a remote repository, but does not make any promises about the ordering in which they are listed. Sure, the most recent one is typically last, but it's not necessarily the most relevant one, especially if that tag was on a branch that didn't get merged yet.

git describe, on the other hand, is trying to give you a concise description of HEAD (by default, or the commit you specify) with respect to the most recent tag reachable from there. If you use your tags only for stable commits, then that's probably going to be the tag you want. Then, once it found that tag, it tells you how many more commits are in HEAD, 606 of them in your example, then "g" (not sure why), then the sha1 of HEAD. This is meant to be a human-readable description of any commit, as in, "oh, you're 606 commits ahead of v2.31.1", but also an unambiguous description, since you get the sha1.

As for adding the --tags option to git describe, you need it if you have tags without annotations, e.g., if some where created using git tag <tagname> <commit> instead of git tag -a <tagname> <commit>. The latter is preferable, since it allows the tagger to describe the contents of the tag, but you can't always count on everyone using it. So it's probably a good idea to add --tags to git describe.

If your repo only contains tags for stable releases, and those releases are not on a different release branch, and you never have hyphens in your tag names, then this would be the most recent stable release that's a parent of HEAD:

git describe --tags | sed 's/-.*//'
0
phd On

The references seem to be sorted alphabetically, not by numeric values, so tail -1 returns not the latest tag but the last one in alphabetic sort. See the entire output of git ls-remote; this is the relevant part:

a320a5c4764b02f0898a98b4b58e11fad5e54e09        refs/tags/v2.3.9
2d9685d47a7e516281aa093bf0cddc8aafa72448        refs/tags/v2.30.0
a8eaf9de52c2d49799d7dc724e688ccbfa74390c        refs/tags/v2.30.0-rc0
cb70effebd91d9e0d4ce81650785e973b5d16ad1        refs/tags/v2.30.0-rc1
a6fee3f22b95c86086b11e3c93d0f1752f9a75c5        refs/tags/v2.30.0-rc2
36b80a59b799802fe776ed390870fe520d262f5c        refs/tags/v2.30.1
4340cdd2bdf420acc349f5cda141141230d5095a        refs/tags/v2.30.2
3e90d4b58f3819cfd58ac61cb8668e83d3ea0563        refs/tags/v2.31.0
4c4ac06896d8b9ec1ded1d5d9aeedb4e8ece44ab        refs/tags/v2.31.0-rc0
6a80b8083c4be2c5703ec122e511a6747af53295        refs/tags/v2.31.0-rc1
ca1f84a036c5658938d72650ae34630ebb140866        refs/tags/v2.31.0-rc2
28afb7555c7013c02b5ee5dc0286546f1f8e2b8f        refs/tags/v2.31.1
67308bd628c6235dbc1bad60c9ad1f2d27d576cc        refs/tags/v2.4.0
92db05f2a784fe0a715de29fc97172eac6bb5089        refs/tags/v2.4.0-rc0
1c8737f27f912aa2438ce3bf9d4e83eb178de00a        refs/tags/v2.4.0-rc1
48e512c8c9397baa5533efa6683f45646234ae1e        refs/tags/v2.4.0-rc2
4beece6ef56cb59ea05afb326fd17c1839b8f282        refs/tags/v2.4.0-rc3
2be062dfcfd1fd4aca132ec02a40b56f63776202        refs/tags/v2.4.1
dd0e3e9610a9b312236fb926c5a9d8cbd73190d9        refs/tags/v2.4.10
4f24175ae76efaf8265e179662a4258387019256        refs/tags/v2.4.11
0a493fee385e530baa898a4ba4c0a64fd02ed0d6        refs/tags/v2.4.12
29932f3915935d773dc8d52c292cadd81c81071d        refs/tags/v2.4.2

To sort by numeric values use --sort=v:refname:

$ git ls-remote --sort=v:refname --refs git://git.kernel.org/pub/scm/git/git.gitt | tail -10
a8eaf9de52c2d49799d7dc724e688ccbfa74390c        refs/tags/v2.30.0-rc0
cb70effebd91d9e0d4ce81650785e973b5d16ad1        refs/tags/v2.30.0-rc1
a6fee3f22b95c86086b11e3c93d0f1752f9a75c5        refs/tags/v2.30.0-rc2
36b80a59b799802fe776ed390870fe520d262f5c        refs/tags/v2.30.1
4340cdd2bdf420acc349f5cda141141230d5095a        refs/tags/v2.30.2
3e90d4b58f3819cfd58ac61cb8668e83d3ea0563        refs/tags/v2.31.0
4c4ac06896d8b9ec1ded1d5d9aeedb4e8ece44ab        refs/tags/v2.31.0-rc0
6a80b8083c4be2c5703ec122e511a6747af53295        refs/tags/v2.31.0-rc1
ca1f84a036c5658938d72650ae34630ebb140866        refs/tags/v2.31.0-rc2
28afb7555c7013c02b5ee5dc0286546f1f8e2b8f        refs/tags/v2.31.1