Tags, Releases & SemVer
Marking Releases
You met tags briefly in the History module - permanent labels on a commit, used to mark the exact point in history you shipped as a version. This section covers using them properly for releases, plus the numbering convention almost every ecosystem expects.
$ git tag -a v1.2.0 -m "Release 1.2.0" # annotated (recommended)
$ git push origin v1.2.0 # tags aren't pushed by default!
$ git tag # list
$ git checkout v1.2.0 # inspect exactly what shipped in that release
Semantic Versioning (SemVer)
Versions are written MAJOR.MINOR.PATCH (e.g. 1.4.2), and each number carries a specific promise to anyone depending on your software:
| Bump | When | Example |
|---|---|---|
| MAJOR | Breaking changes - old code using this might now break | 1.4.2 → 2.0.0 |
| MINOR | New features added, but everything old still works the same | 1.4.2 → 1.5.0 |
| PATCH | Bug fixes only, no new features, nothing about the API changes | 1.4.2 → 1.4.3 |
The whole point of SemVer is that someone depending on your package can glance at a version bump and immediately know how risky it is to upgrade - a PATCH bump is (in theory) always safe to take automatically; a MAJOR bump means "read the changelog before upgrading".
Tip: Annotated tags (-a) store the tagger's name, date and a message, and can additionally be cryptographically signed - always use annotated tags for real releases. Lightweight tags (justgit tag v1, no-a/-m) are fine for quick, private bookmarks you don't intend to publish.
Warning:git pushdoes not push tags, even though it feels like it should after everything else you've pushed. Ship the release marker explicitly withgit push origin <tag>orgit push --tags, or your carefully-labeled v1.2.0 exists only on your own machine and nobody else will ever see it.