Git Commits & Tags
Comprehensive guide to creating meaningful commits, understanding commit anatomy, and using tags for version management.
Understanding Git Commits
What is a Commit?
A commit is a snapshot of your repository at a specific point in time. Each commit contains:
- Commit hash (SHA-1): Unique identifier (e.g.,
b02c9563ad2a7fa368bccbf863d01d338752d247) - Author: Person who wrote the code
- Committer: Person who committed the code (usually same as author)
- Date: When the commit was created
- Message: Description of changes
- Parent commit(s): Previous commit(s) in history
- Tree: Snapshot of all files
Viewing Commit Information
# Show last commit with full details
git log -1
# Show compact one-line format
git log --oneline -5
# Show with author and date
git log --pretty=format:"%H - %an, %ar : %s" -5
# Show full commit details
git log --pretty=full -1
# Show commit with file statistics
git show --stat HEAD
# Show specific commit
git show b02c956
Example Output:
commit b02c9563ad2a7fa368bccbf863d01d338752d247 (HEAD -> main)
Author: donnyaw <donnyaw@gmail.com>
Date: Fri Feb 6 01:03:57 2026 +0000
Initial commit
test.txt | 1 +
1 file changed, 1 insertion(+)
Creating Commits
Basic Commit
# Stage files
git add .
# Commit with message
git commit -m "Add user authentication feature"
Commit with Detailed Message
# Commit with multi-line message
git commit -m "Add user authentication feature
This commit implements:
- JWT token generation
- Login/logout endpoints
- Session management
- Password hashing with bcrypt
Fixes: #123
Closes: #124"
Commit Best Practices
Good Commit Message Structure
<type>: <subject>
<body>
<footer>
Types:
feat: New featurefix: Bug fixdocs: Documentation changesstyle: Code style changes (formatting)refactor: Code refactoringtest: Adding testschore: Maintenance tasks
Examples:
# Feature commit
git commit -m "feat: add password reset functionality"
# Bug fix commit
git commit -m "fix: resolve memory leak in connection pool"
# Documentation commit
git commit -m "docs: update API documentation for v2.0"
# Refactor commit
git commit -m "refactor: optimize database query performance"
Commit All Changes
# Stage and commit all tracked files
git commit -a -m "Update configuration files"
# Shorthand
git commit -am "Update configuration files"
Interactive Commit
# Open editor for detailed commit message
git commit
# Commit with verbose output (shows diff)
git commit -v
# See what would be committed (dry run)
git commit --dry-run
Advanced Commit Operations
Amend Last Commit
# Change last commit message
git commit --amend -m "New commit message"
# Add forgotten files to last commit
git add forgotten-file.txt
git commit --amend --no-edit
# Change author of last commit
git commit --amend --author="donnyaw <donnyaw@gmail.com>"
# Amend with new message in editor
git commit --amend
Partial Commits (Stage Hunks)
# Interactively stage parts of files
git add -p
# Or use interactive mode
git add -i
# Commands in interactive mode:
# y - stage this hunk
# n - don't stage this hunk
# s - split into smaller hunks
# e - manually edit the hunk
Empty Commits
# Create commit without changes (useful for CI triggers)
git commit --allow-empty -m "Trigger CI pipeline"
Fixup and Squash Commits
# Create fixup commit (for interactive rebase)
git commit --fixup=abc123
# Create squash commit
git commit --squash=abc123
# Interactive rebase to apply fixup/squash
git rebase -i --autosquash HEAD~5
Commit Information & History
View Commit Details
# Show specific commit
git show abc123
# Show commit with file changes
git show abc123 --stat
# Show only commit message
git log -1 --pretty=%B abc123
# Show commit author
git log -1 --pretty=format:"%an <%ae>" abc123
# Show commit date
git log -1 --pretty=format:"%cd" abc123
Search Commits
# Search by message
git log --grep="authentication"
# Search by author
git log --author="donnyaw"
# Search by date
git log --since="2 weeks ago"
git log --after="2026-01-01"
git log --before="2026-02-01"
# Search by file
git log -- path/to/file.txt
# Search by code content
git log -S "function_name"
git log -G "regex_pattern"
Commit Statistics
# Show commit count per author
git shortlog -sn
# Show commit activity
git log --stat
# Show file changes per commit
git log --name-status
# Show graph of commits
git log --graph --oneline --all
# Show commits with file changes
git log --pretty=format:"%h %s" --name-only
Git Tags
What are Tags?
Tags are references to specific commits, typically used for marking release versions.
Two types of tags:
- Lightweight tags: Simple pointer to a commit
- Annotated tags: Full objects with tagger info, date, and message (recommended)
Creating Tags
Lightweight Tags
# Create lightweight tag
git tag v1.0.0
# Tag specific commit
git tag v1.0.0 abc123
Annotated Tags (Recommended)
# Create annotated tag
git tag -a v1.0.0 -m "Version 1.0.0 release"
# Tag specific commit
git tag -a v1.0.0 abc123 -m "Version 1.0.0 release"
# Create tag with editor for detailed message
git tag -a v1.0.0
Viewing Tags
# List all tags
git tag
# List tags with pattern
git tag -l "v1.*"
# Show tag with message
git tag -l -n1
# Show detailed tag information
git show v1.0.0
# Show tag with commit info
git show v1.0.0 --stat
Example Output:
tag v1.1.0
Tagger: donnyaw <donnyaw@gmail.com>
Date: Fri Feb 6 01:04:09 2026 +0000
Version 1.1.0 release
commit b02c9563ad2a7fa368bccbf863d01d338752d247
Author: donnyaw <donnyaw@gmail.com>
Date: Fri Feb 6 01:03:57 2026 +0000
Initial commit
Tag Naming Conventions
Semantic Versioning (SemVer)
Format: vMAJOR.MINOR.PATCH
# Major version (breaking changes)
git tag -a v2.0.0 -m "Major release with breaking changes"
# Minor version (new features, backward compatible)
git tag -a v1.1.0 -m "Add new authentication features"
# Patch version (bug fixes)
git tag -a v1.0.1 -m "Fix security vulnerability"
Pre-release Tags
# Alpha release
git tag -a v1.0.0-alpha -m "Alpha release for testing"
# Beta release
git tag -a v1.0.0-beta.1 -m "Beta release 1"
# Release candidate
git tag -a v1.0.0-rc.1 -m "Release candidate 1"
Build Metadata
# With build number
git tag -a v1.0.0+build.123 -m "Build 123"
# With commit hash
git tag -a v1.0.0+$(git rev-parse --short HEAD) -m "Tagged with commit hash"
Pushing Tags
# Push single tag to remote
git push origin v1.0.0
# Push all tags
git push origin --tags
# Push only annotated tags
git push origin --follow-tags
Deleting Tags
# Delete local tag
git tag -d v1.0.0
# Delete remote tag
git push origin :refs/tags/v1.0.0
# Alternative: delete remote tag
git push origin --delete v1.0.0
# Delete multiple tags
git tag -d v1.0.0 v1.0.1 v1.0.2
Checkout Tags
# Checkout specific tag (detached HEAD)
git checkout v1.0.0
# Create branch from tag
git checkout -b hotfix-1.0 v1.0.0
# View files at tag without checkout
git show v1.0.0:path/to/file.txt
Real-World Examples
Example 1: Release Workflow
# Make final changes
git add .
git commit -m "chore: prepare for v1.0.0 release"
# Create release tag
git tag -a v1.0.0 -m "Release version 1.0.0
New features:
- User authentication
- Dashboard improvements
- API documentation
Bug fixes:
- Fix memory leak (#123)
- Resolve login timeout (#124)"
# Push commit and tags
git push origin main
git push origin v1.0.0
Example 2: Hotfix Release
# Checkout release tag
git checkout -b hotfix-1.0.1 v1.0.0
# Fix the bug
git add .
git commit -m "fix: resolve critical security vulnerability"
# Create hotfix tag
git tag -a v1.0.1 -m "Hotfix release v1.0.1 - Security patch"
# Push and merge back
git push origin hotfix-1.0.1
git push origin v1.0.1
Example 3: Find Bug Introduction
# Find when bug was introduced
git log -S "problematic_code" --source --all
# Check commits between tags
git log v1.0.0..v1.1.0 --oneline
# Find commits that modified file
git log --follow -- path/to/file.txt
Commit Message Templates
Create Template File
# Create commit message template
cat > ~/.gitmessage << 'EOF'
# <type>: <subject> (max 50 characters)
# <body> (wrap at 72 characters)
# - What: Describe the changes
# - Why: Explain the motivation
# - How: Highlight implementation details (if complex)
# <footer>
# Fixes: #issue_number
# Closes: #issue_number
# Breaking-Change: describe breaking changes
# Types: feat, fix, docs, style, refactor, test, chore
EOF
# Configure Git to use template
git config --global commit.template ~/.gitmessage
Use Template
# Commit with template (opens editor)
git commit
Conventional Commits
Format
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
Examples
# Feature with scope
git commit -m "feat(auth): add OAuth2 support"
# Fix with issue reference
git commit -m "fix(api): resolve null pointer exception
Checks for null values before processing.
Fixes: #456"
# Breaking change
git commit -m "feat!: change API response format
BREAKING CHANGE: API now returns JSON instead of XML"
# Multiple types
git commit -m "feat(ui): add dark mode
docs: update theme documentation"
Signed Commits
Setup GPG Signing
# Configure GPG key
git config --global user.signingkey YOUR_GPG_KEY_ID
# Enable automatic signing
git config --global commit.gpgsign true
Create Signed Commit
# Sign single commit
git commit -S -m "Signed commit"
# Verify signed commits
git log --show-signature
# Verify specific commit
git verify-commit abc123
Commit Hooks
Pre-commit Hook Example
# Create .git/hooks/pre-commit
cat > .git/hooks/pre-commit << 'EOF'
#!/bin/bash
# Run linter before commit
npm run lint
# Check for debugging code
if git diff --cached | grep -E "console.log|debugger"; then
echo "Error: Remove debugging code before committing"
exit 1
fi
EOF
chmod +x .git/hooks/pre-commit
Best Practices Summary
Do's
-
Write clear, descriptive commit messages
git commit -m "fix: resolve login timeout issue on slow connections" -
Commit logical units of work
- One feature/fix per commit
- Keep commits atomic and focused
-
Use present tense in messages
- "Add feature" not "Added feature"
- "Fix bug" not "Fixed bug"
-
Include issue references
git commit -m "fix: resolve API timeout (#123)" -
Use annotated tags for releases
git tag -a v1.0.0 -m "Release version 1.0.0"
Don'ts
- Don't commit broken code to main
- Don't use vague messages ("update", "fix", "changes")
- Don't commit sensitive data (passwords, API keys)
- Don't mix unrelated changes in one commit
- Don't force push to shared branches (unless necessary)
Quick Reference
Commit Commands
| Command | Purpose |
|---|---|
git commit -m "msg" | Create commit with message |
git commit -am "msg" | Stage and commit tracked files |
git commit --amend | Modify last commit |
git commit -v | Show diff in commit editor |
git show HEAD | Show last commit details |
git log --oneline | Compact commit history |
Tag Commands
| Command | Purpose |
|---|---|
git tag v1.0.0 | Create lightweight tag |
git tag -a v1.0.0 -m "msg" | Create annotated tag |
git tag -l | List all tags |
git show v1.0.0 | Show tag details |
git push origin v1.0.0 | Push single tag |
git push --tags | Push all tags |
git tag -d v1.0.0 | Delete local tag |