Skip to content

Git Tagging & Release Management — Semantic Versioning and Automation

DodaTech 5 min read

In this tutorial, you'll learn about Git Tagging & Release Management. 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 releases — create annotated and lightweight tags, follow semantic versioning, sign tags with GPG, and automate release workflows in CI/CD.

Why It Matters

Tags are permanent landmarks in your project's history. Unlike branches, they don't move. A properly tagged release lets anyone checkout v1.2.3 and get exactly the same code that was deployed to production — essential for debugging, rollbacks, and Compliance.

Real-World Use

A CI pipeline automatically creates a v1.2.3 annotated tag when the release branch is merged to main. Operations deploys the tag to production, and when a bug is reported, developers can git checkout v1.2.3 to reproduce the exact deployed state.

Types of Tags

graph LR
    A[Git Tags] --> B[Lightweight]
    A --> C[Annotated]
    B --> D[Just a pointer
to a commit] C --> E[Full object with:
- Tagger name/email
- Date
- Message
- GPG signature] C --> F[Recommended for releases]
# Lightweight tag (just a name pointing to a commit)
git tag v1.0.0

# Annotated tag (recommended for releases)
git tag -a v1.0.0 -m "Release v1.0.0 - Initial production release"

Creating Annotated Tags

# Tag the current commit
git tag -a v1.2.0 -m "Release v1.2.0 - Add payment processing"
git tag -a v1.2.1 -m "Release v1.2.1 - Fix login timeout bug"

# Tag a specific commit (not HEAD)
git tag -a v1.0.0 a1b2c3 -m "Release v1.0.0"

# View tag details
git show v1.2.0
# tag v1.2.0
# Tagger: Jane Doe <jane@example.com>
# Date:   Mon Mar 4 14:30:00 2024
#
# Release v1.2.0 - Add payment processing
#
# commit a1b2c3d4e5f6...
# Author: John <john@example.com>
#     Implement Stripe payment gateway

Semantic Versioning with Tags

Follow the MAJOR.MINOR.PATCH scheme:

# PATCH: backwards-compatible bug fixes
git tag -a v1.2.1 -m "v1.2.1 - fix login redirect"

# MINOR: backwards-compatible new features
git tag -a v1.3.0 -m "v1.3.0 - add dark mode"

# MAJOR: breaking changes
git tag -a v2.0.0 -m "v2.0.0 - complete API rewrite"

# Pre-release versions
git tag -a v2.0.0-beta.1 -m "v2.0.0-beta.1"
git tag -a v2.0.0-rc.1 -m "v2.0.0-rc.1 (release candidate)"

Listing and Searching Tags

# List all tags
git tag
# v1.0.0
# v1.1.0
# v1.2.0
# v2.0.0-beta.1

# Filter by pattern
git tag -l "v1.*"
# v1.0.0
# v1.1.0
# v1.2.0

# Show tags with commit metadata
git tag -n5
# v1.0.0          Release v1.0.0
# v1.1.0          Release v1.1.0 - Add user profiles
# v1.2.0          Release v1.2.0 - Add payment processing

Pushing and Fetching Tags

# Push a specific tag
git push origin v1.2.0
# Enumerating objects: 1, done.
# Writing objects: 100% (1/1), 162 bytes
# To github.com:user/project.git
#  * [new tag]         v1.2.0 -> v1.2.0

# Push all tags
git push origin --tags

# Fetch tags from remote
git fetch --tags
# From github.com:user/project
#  * [new tag]         v1.2.0 -> v1.2.0
#  * [new tag]         v1.3.0 -> v1.3.0

Signing Tags with GPG

# Configure GPG signing
git config user.signingkey ABCDEF1234567890
git config tag.gpgSign true

# Create a signed tag
git tag -s v1.2.0 -m "Release v1.2.0"
# You need a passphrase to unlock the secret key for...

# Verify the signature
git tag -v v1.2.0
# object a1b2c3d4e5f6...
# type commit
# tag v1.2.0
# tagger Jane Doe <jane@example.com> 1709553000 +0000
# gpg: Signature made Mon Mar 4 14:30:00 2024 UTC
# gpg: Good signature from "Jane Doe <jane@example.com>"

Automating Releases with CI

# Example GitHub Actions workflow (.github/workflows/release.yml)
name: Create Release Tag
on:
  push:
    branches: [main]

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Bump version and push tag
        id: tag
        uses: anothrNick/github-tag-action@1.67.0
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          DEFAULT_BUMP: patch
          WITH_V: true

      - name: Create GitHub Release
        uses: softprops/action-gh-release@v1
        with:
          tag_name: ${{ steps.tag.outputs.new_tag }}
          generate_release_notes: true

Deleting Tags

# Delete a local tag
git tag -d v1.0.0
# Deleted tag 'v1.0.0'

# Delete a remote tag
git push origin --delete v1.0.0
#  - [deleted]         v1.0.0

# Or delete with colon syntax
git push origin :refs/tags/v1.0.0

Common Pitfalls

Mistake Solution
Using lightweight tags for releases Always use git tag -a for releases — annotated tags have metadata
Forgetting to push tags Tags are local until git push origin <tagname> or --tags
Moving a tag that was already pushed Delete and recreate — never move a published release tag
Tagging the wrong commit Delete the tag and re-tag the correct commit

Practice Questions

  1. What is the difference between a lightweight tag and an annotated tag?
  2. What does git push origin --tags do?
  3. Why should you sign release tags with GPG?

FAQs

Can I move a tag to a different commit?

Technically yes — git tag -f v1.0.0 <new-commit> force-updates a local tag. However, you should never move a published release tag. If you tagged the wrong commit, delete the tag and create a new one.

How do tags interact with git bisect?

Tags work perfectly with bisect — you can use them as good/bad markers directly: git bisect good v1.0.0 and git bisect bad v2.0.0. Tags are stable references that never move, making them ideal bisect anchors.

What is the difference between a tag and a branch?

A branch moves with each new commit. A tag is a permanent marker at a specific commit. Branches are for active development; tags are for historical milestones (releases, versions). Use branches to work, tags to remember.

Next Steps

After mastering tagging and release management, set up Git Hooks to automate version bumping, or learn version control strategies for Monorepo releases.


Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro