Working with Tags
Tags in Git are references that point to specific commits in your repository history. They are typically used to mark release points (v1.0, v2.0, etc.) and capture important milestones in your project. Unlike branches, tags don't change - they permanently mark a specific point in time.
Understanding Tags
Git supports two types of tags:
Lightweight Tags:
- Simple pointer to a commit
- Just a name for a commit hash
- No additional information stored
- Like a bookmark
Annotated Tags:
- Full objects in Git database
- Contains tagger name, email, and date
- Can include a message
- Can be signed and verified with GPG
- Recommended for releases
Best Practice: Always use annotated tags for releases and public version markers. Use lightweight tags for temporary markers or personal use only.
Creating Lightweight Tags
Creating a lightweight tag is simple - just provide a tag name:
# Create a lightweight tag at current commit
git tag v1.0.0
# Create a lightweight tag at specific commit
git tag v0.9.0 abc1234
# View the tag
git show v1.0.0
Lightweight tags are just pointers - no additional metadata is stored.
Creating Annotated Tags
Annotated tags are more comprehensive and recommended for releases:
# Create annotated tag with message
git tag -a v1.0.0 -m "Release version 1.0.0"
# Create annotated tag with editor for longer message
git tag -a v1.0.0
# Tag a specific commit
git tag -a v0.9.0 abc1234 -m "Beta release"
# View detailed tag information
git show v1.0.0
When you view an annotated tag with git show, you'll see the tagger information, date, message, and commit details.
Note: Annotated tags include the tagger's name, email, timestamp, and a tagging message. This makes them ideal for marking official releases.
Semantic Versioning
The most common convention for version tags is Semantic Versioning (SemVer):
Format: MAJOR.MINOR.PATCH
v1.0.0 - Initial stable release
v1.0.1 - Patch: Bug fixes (backward compatible)
v1.1.0 - Minor: New features (backward compatible)
v2.0.0 - Major: Breaking changes (not backward compatible)
Examples:
git tag -a v1.0.0 -m "First stable release"
git tag -a v1.0.1 -m "Fix critical security bug"
git tag -a v1.1.0 -m "Add user authentication feature"
git tag -a v2.0.0 -m "Complete API redesign"
Tip: Prefix tags with "v" (v1.0.0) rather than just numbers (1.0.0). This is the industry standard and helps distinguish version tags from other numeric identifiers.
Listing Tags
Git provides several ways to view your tags:
# List all tags
git tag
# List tags matching a pattern
git tag -l "v1.*"
git tag -l "v2.0.*"
# Show tag details (annotated tags only)
git tag -n
git tag -n5 # Show first 5 lines of message
# Show detailed information about a specific tag
git show v1.0.0
Pushing Tags to Remote
By default, git push does NOT push tags to remote repositories. You must push them explicitly:
# Push a single tag
git push origin v1.0.0
# Push all tags at once
git push origin --tags
# Push all tags (including lightweight)
git push origin --tags
# Push only annotated tags
git push origin --follow-tags
Warning: git push --tags pushes ALL tags (lightweight and annotated). Use --follow-tags to push only annotated tags automatically with commits.
Checking Out Tags
You can view your code at a specific tag, but this puts you in "detached HEAD" state:
# Checkout a tag (detached HEAD state)
git checkout v1.0.0
# Create a new branch from a tag
git checkout -b hotfix-branch v1.0.0
# View files at a specific tag without checking out
git show v1.0.0:path/to/file.txt
Detached HEAD: When you checkout a tag, you're not on any branch. Any commits you make won't belong to a branch and could be lost. Always create a new branch if you want to make changes from a tagged point.
Deleting Tags
Sometimes you need to remove tags (typos, wrong version, etc.):
# Delete local tag
git tag -d v1.0.0
# Delete remote tag (two methods)
git push origin --delete v1.0.0
git push origin :refs/tags/v1.0.0
# Delete multiple tags
git tag -d v1.0.0 v1.0.1 v1.0.2
Important: If you delete and recreate a tag with the same name, it can cause confusion for other developers. Communicate with your team before modifying published tags.
Practical Release Workflow
Here's a typical workflow for creating a release with tags:
# 1. Ensure you're on the main branch and it's up to date
git checkout main
git pull origin main
# 2. Make sure all tests pass and code is ready
# Run your test suite here
# 3. Update version numbers in your code (package.json, etc.)
# Edit files as needed
# 4. Commit version bump
git add .
git commit -m "Bump version to 1.2.0"
# 5. Create annotated tag
git tag -a v1.2.0 -m "Release version 1.2.0
New features:
- Added user dashboard
- Improved performance
- Fixed critical bugs"
# 6. Push commits and tag
git push origin main
git push origin v1.2.0
# 7. Create release notes on GitHub (optional)
Advanced Tag Operations
Some advanced scenarios you might encounter:
# Tag a specific file state (not recommended, but possible)
git tag snapshot-config abc1234 path/to/config.php
# Find which tag contains a commit
git tag --contains abc1234
# Find tags reachable from a commit
git describe --tags
# List tags sorted by version
git tag --sort=v:refname
# List tags sorted by date
git tag --sort=-creatordate
Comparing Tags
You can compare different versions of your code using tags:
# Show differences between two tags
git diff v1.0.0 v1.1.0
# Show log between two tags
git log v1.0.0..v1.1.0
# Show files changed between tags
git diff --name-only v1.0.0 v1.1.0
# Generate changelog between tags
git log v1.0.0..v1.1.0 --oneline --no-merges
Practice Exercise:
Create a release workflow:
- Create a new repository or use an existing one
- Make several commits to simulate development
- Create an annotated tag
v1.0.0 for your first release
- Make more commits with new features
- Create tag
v1.1.0
- List all tags and view their details
- Compare the differences between v1.0.0 and v1.1.0
- Practice pushing tags to a remote repository
Commands to use:
git tag -a v1.0.0 -m "First stable release"
git tag -a v1.1.0 -m "Added new features"
git tag
git show v1.0.0
git diff v1.0.0 v1.1.0
git push origin --tags
Common Tag Mistakes
❌ Using lightweight tags for releases
git tag v1.0.0
✓ Use annotated tags instead
git tag -a v1.0.0 -m "Release 1.0.0"
❌ Forgetting to push tags
git push origin main
✓ Push tags explicitly
git push origin v1.0.0
❌ Tagging without testing
git tag -a v1.0.0 -m "Release"
✓ Test thoroughly first
# Run tests, verify everything works
git tag -a v1.0.0 -m "Release"
Summary
In this lesson, you learned:
- Tags mark specific points in Git history, typically for releases
- Lightweight tags are simple pointers; annotated tags include metadata
- Use Semantic Versioning (MAJOR.MINOR.PATCH) for version numbers
- Tags must be pushed explicitly to remote repositories
- Checking out tags puts you in detached HEAD state
- Annotated tags are recommended for all public releases
- Tags can be compared to see changes between versions
Next Up: In the next lesson, we'll learn about stashing changes - a powerful feature for temporarily storing work without committing!