[GH-ISSUE #394] Make semver compatible with "git describe"? #7269

Closed
opened 2026-06-20 17:13:25 -05:00 by GiteaMirror · 12 comments
Owner

Originally created by @wolframroesler on GitHub (Sep 11, 2017).
Original GitHub issue: https://github.com/semver/semver/issues/394

It would be nice if semantic version numbers were compatible with the version numbers created with git describe. For example, my project's current output of git describe is 2.15.3-19-gfde9682, which means "19 commits past release 2.15.3, the latest commit ID is fde9682". The g stands for git, the 2.15.3 is taken from the latest annotated git tag, which was created by git flow.

Any chance to incorporate that into semver?

Originally created by @wolframroesler on GitHub (Sep 11, 2017). Original GitHub issue: https://github.com/semver/semver/issues/394 It would be nice if semantic version numbers were compatible with the version numbers created with `git describe`. For example, my project's current output of `git describe` is `2.15.3-19-gfde9682`, which means "19 commits past release 2.15.3, the latest commit ID is fde9682". The g stands for git, the 2.15.3 is taken from the latest annotated git tag, which was created by git flow. Any chance to incorporate that into semver?
Author
Owner

@FichteFoll commented on GitHub (Sep 11, 2017):

The commit ID is meta data and can easily be made compatible.

The "N commits past release X" part not so much. See #200 for an issue discussing this extensively.

I highly doubt the exact format would be supported, because hyphens are valid in pre-release and build metadata identifiers, but if #200 was addressed, you could easily make it compatible with an sed call, replacing the hyphens with the correct separator characters.

<!-- gh-comment-id:328551117 --> @FichteFoll commented on GitHub (Sep 11, 2017): The commit ID is meta data and can easily be made compatible. The "N commits past release X" part not so much. See #200 for an issue discussing this extensively. I highly doubt the exact format would be supported, because hyphens are valid in pre-release and build metadata identifiers, but if #200 was addressed, you could easily make it compatible with an `sed` call, replacing the hyphens with the correct separator characters.
Author
Owner
<!-- gh-comment-id:335007261 --> @imhomos commented on GitHub (Oct 8, 2017): https://www.google.com/search?client=opera&q=Szechuan+Sauce+Recipe+-+Genius+Kitchen&sourceid=opera&ie=UTF-8&oe=UTF-8
Author
Owner

@jwdonahue commented on GitHub (Nov 28, 2017):

@wolframroesler, I think technically, SemVer 2.0.0 already has you covered. The '-19-gfde9682' part of your git tag is a valid prerelease tag in SemVer, however, according the precedence rules, this entire pr tag must be sorted lexically in ASCII sort order, so to preserve your "19th build after 2.15.3" semantics, the tag should have the form '-19.gfde9682', now the first identifier is '19' which as all numeric and sorts numerically, which is nearly the behavior you are looking for. With the first check-in after 2.15.3+Any.Meta, you must bump at least the patch number, so that now you have a time sequence like:

2.15.2-789.whatever
2.15.3
2.15.4-1.whatever
2.15.4-2.whatever

This way you don't burn through patch numbers except for releases, you achieve compliance with SemVer and if you want the latest, the precedence rules would produce 2.15.4-2.whatever and your last stable release was 2.15.3.

I recommend you put the git hash in a meta field. It's too random to be of any value in the sortable prerlease tag.

<!-- gh-comment-id:347426836 --> @jwdonahue commented on GitHub (Nov 28, 2017): @wolframroesler, I think technically, SemVer 2.0.0 already has you covered. The '-19-gfde9682' part of your git tag is a valid prerelease tag in SemVer, however, according the precedence rules, this entire pr tag must be sorted lexically in ASCII sort order, so to preserve your "19th build after 2.15.3" semantics, the tag should have the form '-19.gfde9682', now the first identifier is '19' which as all numeric and sorts numerically, which is nearly the behavior you are looking for. With the first check-in after 2.15.3+Any.Meta, you must bump at least the patch number, so that now you have a time sequence like: 2.15.2-789.whatever 2.15.3 2.15.4-1.whatever 2.15.4-2.whatever This way you don't burn through patch numbers except for releases, you achieve compliance with SemVer and if you want the latest, the precedence rules would produce 2.15.4-2.whatever and your last stable release was 2.15.3. I recommend you put the git hash in a meta field. It's too random to be of any value in the sortable prerlease tag.
Author
Owner

@wolframroesler commented on GitHub (Feb 1, 2018):

That settles it for me, thanks. Closing the issue since #200 says it all.

<!-- gh-comment-id:362319090 --> @wolframroesler commented on GitHub (Feb 1, 2018): That settles it for me, thanks. Closing the issue since #200 says it all.
Author
Owner

@KyNorthstar commented on GitHub (Sep 21, 2019):

Perhaps git describe should be made compatible with SemVer

<!-- gh-comment-id:533770971 --> @KyNorthstar commented on GitHub (Sep 21, 2019): Perhaps [`git describe` should be made compatible with SemVer](https://git-scm.com/community)
Author
Owner

@wizzwizz4 commented on GitHub (Sep 21, 2019):

@BenLeggiero That'd be a breaking change, unless there was a flag you could use to do so.

<!-- gh-comment-id:533787634 --> @wizzwizz4 commented on GitHub (Sep 21, 2019): @BenLeggiero That'd be a breaking change, unless there was a flag you could use to do so.
Author
Owner

@jwdonahue commented on GitHub (Sep 21, 2019):

@BenLeggiero

Not all repository tags contain version strings. From the docs:

--all
Instead of using only the annotated tags, use any ref found in refs/ namespace. This option enables matching any known branch, remote-tracking branch, or lightweight tag.

While it is possible and fairly common, to tag commit Id's with version numbers, that is not the only purpose for tags in a repo. Perhaps it would be nice to have a --SemVer option to find tags that contain SemVer strings, but that is something you'd have to take up with the maintainers of Git.

<!-- gh-comment-id:533809506 --> @jwdonahue commented on GitHub (Sep 21, 2019): @BenLeggiero Not all repository tags contain version strings. From the docs: > --all > Instead of using only the annotated tags, use any ref found in refs/ namespace. This option enables matching any known branch, remote-tracking branch, or lightweight tag. While it is possible and fairly common, to tag commit Id's with version numbers, that is not the only purpose for tags in a repo. Perhaps it would be nice to have a `--SemVer` option to find tags that contain SemVer strings, but that is something you'd have to take up with the maintainers of Git.
Author
Owner

@RolfBippus commented on GitHub (Jan 6, 2022):

@jwdonahue
Just a minor remark to the above.
When using pre-release tags, which are prefixed by '-' in semver, shouldn't you use '+' for the 'commits ahead'(Meta) part:

for example:
git describe --long delivers '2.15.4-pre-2-g<hash>'
semver compatible version could be '2.15.4-pre+2.<hash>' (loose=True)

That way:

'2.15.4-pre' < '2.15.4-pre+1.<hash>' < '2.15.4' < '2.15.4+1.<hash>'

otherwise you'd get

'2.15.4-2' < '2.15.4'

but since (from git describe) 2.15.4-2 is ahead of 2.15.4 by 2 commits (and not a prerelease), this might not be what you intended.

<!-- gh-comment-id:1006716542 --> @RolfBippus commented on GitHub (Jan 6, 2022): @jwdonahue Just a minor remark to the above. When using pre-release tags, which are prefixed by '-' in semver, shouldn't you use '+' for the 'commits ahead'(Meta) part: for example: `git describe --long` delivers `'2.15.4-pre-2-g<hash>'` semver compatible version could be `'2.15.4-pre+2.<hash>'` (loose=True) That way: `'2.15.4-pre'` **<** `'2.15.4-pre+1.<hash>'` **<** `'2.15.4'` **<** `'2.15.4+1.<hash>'` otherwise you'd get `'2.15.4-2'` **<** `'2.15.4'` but since (from git describe) 2.15.4-2 is ahead of 2.15.4 by 2 commits (and not a prerelease), this might not be what you intended.
Author
Owner

@ekzyis commented on GitHub (Mar 6, 2023):

I am just using piping the output into sed now:

$ git describe --tags
v0.3.1-2-g4291ac9
$ git describe --tags | sed -e 's/-[[:digit:]]\+-g/+/'
v0.3.1+4291ac9

I think this is semver compatible now?

Maybe this helps someone.

<!-- gh-comment-id:1455696774 --> @ekzyis commented on GitHub (Mar 6, 2023): I am just using piping the output into `sed` now: ```txt $ git describe --tags v0.3.1-2-g4291ac9 $ git describe --tags | sed -e 's/-[[:digit:]]\+-g/+/' v0.3.1+4291ac9 ``` I think this is semver compatible now? Maybe this helps someone.
Author
Owner

@jwdonahue commented on GitHub (Mar 9, 2023):

@ekzyis The 'v' prefix is non-compliant, as it was removed in an early beta version of SemVer, but some of the packaging tools will strip or ignore it.

<!-- gh-comment-id:1462428838 --> @jwdonahue commented on GitHub (Mar 9, 2023): @ekzyis The 'v' prefix is non-compliant, as it was removed in an early beta version of SemVer, but some of the packaging tools will strip or ignore it.
Author
Owner

@jonasgeiler commented on GitHub (Sep 14, 2024):

@ekzyis @jwdonahue
Based on your answer and because I wanted to retain the revision number (aka. number of additional commits), I now use the following:

git describe --long --tags --abbrev=7
# v2.9.0-beta.3-0-gf831827

git describe --long --tags --abbrev=7 | sed -e 's/^v//' -e 's/-\([[:digit:]]\+\)-\(g[[:alnum:]]\{7\}\)$/-r.\1+\2/'
# 2024.9.0-beta.3-r.0+gf831827

Valid semver and nicely sortable, as far as I know.
Btw, if you change the value for --abbrev you should also change the counter in the sed expression at \{7\}.

<!-- gh-comment-id:2350946563 --> @jonasgeiler commented on GitHub (Sep 14, 2024): @ekzyis @jwdonahue Based on your answer and because I wanted to retain the revision number (aka. number of additional commits), I now use the following: ```bash git describe --long --tags --abbrev=7 # v2.9.0-beta.3-0-gf831827 git describe --long --tags --abbrev=7 | sed -e 's/^v//' -e 's/-\([[:digit:]]\+\)-\(g[[:alnum:]]\{7\}\)$/-r.\1+\2/' # 2024.9.0-beta.3-r.0+gf831827 ``` Valid semver and nicely sortable, as far as I know. Btw, if you change the value for `--abbrev` you should also change the counter in the sed expression at `\{7\}`.
Author
Owner

@FichteFoll commented on GitHub (Sep 15, 2024):

Note that the 3-r pre-release segment will be compared lexicographically and not numerically, even with the original version tag 2.9.0-beta.3. It is considered of higher precedence, however, but you could also have achieved that by simply adding more pre-release fields, i.e. replace 3-r with 3.r as that would work for non-single-digit versions as well (because 3-r > 11). That same algorithm would then fail for non-pre-release tags, however. And you would need some logic to not apply the pre-release logic for commits that have a tag pointing to them, e.g. v0.1.11-0-g1234567.

<!-- gh-comment-id:2351535995 --> @FichteFoll commented on GitHub (Sep 15, 2024): Note that the `3-r` pre-release segment will be compared lexicographically and not numerically, even with the original version tag `2.9.0-beta.3`. It is considered of higher precedence, however, but you could also have achieved that by simply adding more pre-release fields, i.e. replace `3-r` with `3.r` as that would work for non-single-digit versions as well (because `3-r` > `11`). That same algorithm would then fail for non-pre-release tags, however. And you would need some logic to not apply the pre-release logic for commits that have a tag pointing to them, e.g. `v0.1.11-0-g1234567`.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/semver#7269