Skip to main content

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 feature
  • fix: Bug fix
  • docs: Documentation changes
  • style: Code style changes (formatting)
  • refactor: Code refactoring
  • test: Adding tests
  • chore: 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:

  1. Lightweight tags: Simple pointer to a commit
  2. 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
# 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

  1. Write clear, descriptive commit messages

    git commit -m "fix: resolve login timeout issue on slow connections"
  2. Commit logical units of work

    • One feature/fix per commit
    • Keep commits atomic and focused
  3. Use present tense in messages

    • "Add feature" not "Added feature"
    • "Fix bug" not "Fixed bug"
  4. Include issue references

    git commit -m "fix: resolve API timeout (#123)"
  5. Use annotated tags for releases

    git tag -a v1.0.0 -m "Release version 1.0.0"

Don'ts

  1. Don't commit broken code to main
  2. Don't use vague messages ("update", "fix", "changes")
  3. Don't commit sensitive data (passwords, API keys)
  4. Don't mix unrelated changes in one commit
  5. Don't force push to shared branches (unless necessary)

Quick Reference

Commit Commands

CommandPurpose
git commit -m "msg"Create commit with message
git commit -am "msg"Stage and commit tracked files
git commit --amendModify last commit
git commit -vShow diff in commit editor
git show HEADShow last commit details
git log --onelineCompact commit history

Tag Commands

CommandPurpose
git tag v1.0.0Create lightweight tag
git tag -a v1.0.0 -m "msg"Create annotated tag
git tag -lList all tags
git show v1.0.0Show tag details
git push origin v1.0.0Push single tag
git push --tagsPush all tags
git tag -d v1.0.0Delete local tag