Git Tags — Versioning and Releases
DodaTech
3 min read
In this tutorial, you'll learn about Git Tags. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.
What You'll Learn
Use Git tags to mark specific points in history — create lightweight and annotated tags, push them to remotes, and use them for versioned releases.
Why It Matters
Tags are how you mark releases, versions, and milestones. They let you quickly go back to any release without remembering commit hashes.
Real-World Use
Tagging a release as v1.2.3 so production always deploys from that tag, or marking v2.0.0-rc1 for a release candidate.
Lightweight vs Annotated Tags
| Aspect | Lightweight | Annotated |
|---|---|---|
| Storage | Just a pointer | Full object in Git database |
| Metadata | None | Tagger name, email, date, message |
| Signing | No | Can be GPG-signed |
| Use case | Private, temporary markers | Public releases |
| Creation | git tag v1.0 |
git tag -a v1.0 -m "v1.0 release" |
Creating Tags
# Lightweight tag (just a name for a commit)
git tag v1.0.0
# Annotated tag (recommended for releases)
git tag -a v1.0.0 -m "Version 1.0.0 — Initial stable release"
# Tag a specific commit (instead of HEAD)
git tag -a v1.0.0 a1b2c3 -m "Version 1.0.0"
# Tag with GPG signature
git tag -s v1.0.0 -m "Signed release v1.0.0"
# Tag for a release candidate
git tag -a v2.0.0-rc1 -m "Release candidate 1 for v2.0.0"
Listing Tags
# List all tags
git tag
# Search for tags matching a pattern
git tag -l "v1.*"
# List tags with messages
git tag -n
# Show tag details
git show v1.0.0
Pushing Tags
# Push a specific tag
git push origin v1.0.0
# Push all tags
git push --tags
# Delete a remote tag
git push --delete origin v1.0.0
# Delete a local tag
git tag -d v1.0.0
Semantic Versioning with Tags
Use SemVer for tag names:
vMAJOR.MINOR.PATCH
v1.0.0 # Initial release
v1.1.0 # Backward-compatible feature add
v1.1.1 # Bug fix
v2.0.0 # Breaking change
# With pre-release labels:
v2.0.0-alpha.1
v2.0.0-beta.1
v2.0.0-rc.1
Creating a Release Workflow
# 1. Prepare the release
git checkout main
git pull
# Run tests, update version numbers, etc.
# 2. Create the tag
git tag -a v1.2.0 -m "Release v1.2.0 — New payment feature"
# 3. Push the tag
git push origin v1.2.0
# 4. Create a release on GitHub
gh release create v1.2.0 \
--title "v1.2.0 — New Payment Feature" \
--notes "Added Stripe integration, fixed CSV export bug" \
--target main
Checking Out a Tag
# View the code at a tag
git checkout v1.0.0
# ⚠️ This puts you in "detached HEAD" state
# You can view/test but shouldn't make changes here
# If you need to work from a tag, create a branch:
git checkout -b release/v1.0.x v1.0.0
Using Tags for Deployment
# In CI/CD (GitHub Actions example)
name: Deploy from Tag
on:
push:
tags:
- 'v*'
jobs:
deploy:
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.ref }} # Checkout the tag
- run: ./deploy.sh
Migrating Tags
# Move a tag to the current commit
git tag -f v1.0.0 HEAD
# Rename a tag (create new, delete old)
git tag v1.0.1 v1.0.0
git tag -d v1.0.0
git push origin v1.0.1
git push --delete origin v1.0.0
Best Practices
| Practice | Why |
|---|---|
| Always use annotated tags for releases | Metadata and signing |
| Follow SemVer | Clear version meaning |
| Tag after merge to main | Stable commit |
| Push tags separately from branches | Cleaner history |
| Never change a published tag | Others may depend on it |
| Document what each tag means | Team alignment |
← Previous
Git Bisect — Find the Commit That Introduced a Bug
Next →
Git Log — Powerful Commit History Filtering
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro