Tagging Releases & Workflow Patterns
IntermediateTags are permanent named pointers to specific commits — ideal for releases. Understanding Git workflows (GitHub Flow, Git Flow, trunk-based) helps teams decide how to structure branches and releases.
Overview
Versioned releases need stable, named references — that is what tags are for. Unlike branches, tags never move once created. Lightweight tags are just pointers; annotated tags (recommended for releases) store the tagger name, date, message, and can be GPG-signed. Beyond tags, choosing the right branching workflow for your team is a critical architectural decision. GitHub Flow is simple and fast for continuous delivery. Git Flow suits projects with scheduled releases. Trunk-based development scales to large teams using feature flags.
Annotated Tags for Releases
Always use annotated tags (-a) for release versions — they store who created the tag, when, and why. Lightweight tags (no -a) are just pointers, no metadata.
# Create an annotated tag (recommended for releases)
git tag -a v2.0.0 -m "Release 2.0.0 — payment gateway, cart redesign"
# Tag a specific past commit
git tag -a v1.9.1 9d2e441 -m "Hotfix: null pointer in checkout"
# List all tags
git tag
git tag -l "v2.*" # filter by pattern
# Show tag details
git show v2.0.0
# tag v2.0.0
# Tagger: Akshay <a@example.com>
# Date: Mon Jan 15 2024
# Release 2.0.0 — payment gateway, cart redesign
# commit a3f8c12...
# Push tags to remote (tags are NOT pushed by default)
git push origin v2.0.0 # push one tag
git push origin --tags # push all tags
# Delete a tag
git tag -d v2.0.0 # local
git push origin --delete v2.0.0 # remoteBranching Workflows Compared
Three workflows dominate the industry. GitHub Flow is simple: one main branch, short-lived feature branches, PR → merge to main → deploy. Git Flow has develop, release, and hotfix branches — suited for versioned software. Trunk-based development keeps everyone on main with feature flags.
// ── GITHUB FLOW (recommended for most teams) ──
//
// main: ────────────────────────────────â–º (always deployable)
// │ │
// feature/A feature/B
// │ │
// (PR + review) (PR + review)
// â””───â–º merge â””───â–º merge
//
// Rules: main is always deployable; branches are short-lived
// ── GIT FLOW (versioned releases) ──
//
// main: ──────────────────────────â–º (production releases)
// │ │
// develop: ──────────────────────────â–º (integration)
// │ │
// feature/A feature/B
// â””──â–º develop â””──â–º develop
// │
// release/v2.0 ──â–º main (tag v2.0)
// │
// hotfix/v2.0.1 ──â–º main + develop
// ── TRUNK-BASED DEVELOPMENT (large teams / CI/CD) ──
//
// Everyone commits to main (or short-lived branches < 1 day)
// Feature flags control visibility:
// if (featureFlags.newCheckout) { <new code> } else { <old code> }Key Points to Remember
- 1Annotated tags (-a) store tagger name, date, and message — always use for releases; lightweight tags are just pointers
- 2Tags must be pushed explicitly: git push origin --tags (they are not included in git push)
- 3GitHub Flow: main is always deployable, short-lived feature branches, PR to merge
- 4Git Flow: separate develop and main branches, feature/release/hotfix branch types
- 5Trunk-based development: everyone on main, feature flags control visibility — scales best
Interview Questions
Sign in to ask AriaWhat is the difference between a lightweight and an annotated tag?
Compare GitHub Flow and Git Flow. When would you use each?
Why aren't Git tags pushed automatically with git push?
Ask Aria about Tagging Releases & Workflow Patterns
Your personal AI tutor — ask anything about this concept
Revision Status
Personal Notes
Sign in to save personal notes for this topic.
Discussion
Sign in to join the discussion.