Git - Committing
Commits are the building blocks of your project's history. A good commit is like a snapshot that tells a clear story about what changed and why. Master the art of committing to create maintainable, understandable projects.
What is a Commit?
A commit is a permanent snapshot of your project at a specific point in time. Each commit contains:
- Snapshot of files: All staged changes
- Metadata: Author, timestamp, commit message
- Unique ID: SHA-1 hash for identification
- Parent pointer: Link to previous commit(s)
Commit Object:
├── Tree: abc123 (snapshot of files)
├── Parent: def456 (previous commit)
├── Author: John Doe
├── Date: 2023-10-25 14:30:22
└── Message: "Add user authentication feature"
Basic Commit Commands
Standard Commit
# Stage files first, then commit
git add README.md
git commit -m "Update project description"
[main a1b2c3d] Update project description
1 file changed, 3 insertions(+), 1 deletion(-)
Commit with Editor
git commit
This opens your configured editor with a template:
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch main
# Changes to be committed:
# modified: README.md
#
Commit All Tracked Files
git commit -am "Quick fix for login bug"
-a
only stages tracked files. New files still need git add
first.
Writing Great Commit Messages
Your commit message is how you communicate with your future self and teammates. Follow these conventions:
The Seven Rules
- Separate subject from body with blank line
- Limit subject line to 50 characters
- Capitalize the subject line
- Don't end subject line with period
- Use imperative mood ("Add" not "Added")
- Wrap body at 72 characters
- Use body to explain what and why, not how
Good Examples
git commit -m "Add user registration form"
git commit -m "Fix memory leak in image processing
The image cache wasn't properly releasing memory after processing
large files. This caused the application to crash after processing
about 50 high-resolution images.
Changes:
- Add proper cleanup in ImageProcessor.dispose()
- Implement WeakReference for cached thumbnails
- Add unit tests for memory usage patterns
Fixes #Issue-123"
Bad Examples
git commit -m "stuff"
git commit -m "changes"
git commit -m "fixed it"
git commit -m "WIP"
git commit -m "asdf"
git commit -m "Updated files and made some changes to the code"
Commit Message Templates
Set Up Template
cat > ~/.gitmessage << EOF
# Title: Summary, imperative, start upper case, don't end with a period
# No more than 50 chars. #### 50 chars is here: #
# Remember blank line between title and body.
# Body: Explain *what* and *why* (not *how*). Include task ID (Jira issue).
# Wrap at 72 chars. ################################## which is here: #
# At the end: Include Co-authored-by for all contributors.
# Include at least one empty line before it. Format:
# Co-authored-by: name
#
# How to Write a Git Commit Message:
# https://chris.beams.io/posts/git-commit/
#
# 1. Separate subject from body with a blank line
# 2. Limit the subject line to 50 characters
# 3. Capitalize the subject line
# 4. Do not end the subject line with a period
# 5. Use the imperative mood in the subject line
# 6. Wrap the body at 72 characters
# 7. Use the body to explain what and why vs. how
EOF
git config --global commit.template ~/.gitmessage
Conventional Commits
Many teams use standardized commit formats:
type(scope): description
[optional body]
[optional footer(s)]
feat(auth): add OAuth2 integration
fix(ui): resolve button alignment issue
docs(readme): update installation instructions
style(css): fix indentation in main.css
refactor(api): simplify user validation logic
test(auth): add unit tests for login flow
chore(deps): update dependencies to latest versions
Commit Variations
Amending Commits
Fix the most recent commit:
git commit --amend -m "Better commit message"
git add forgotten-file.txt
git commit --amend --no-edit
Empty Commits
Sometimes useful for triggering CI/CD or marking points:
git commit --allow-empty -m "Trigger deployment"
Signed Commits
For security and verification:
# Sign with GPG key
git commit -S -m "Add secure payment processing"
# Configure automatic signing
git config --global commit.gpgsign true
Practical Commit Scenarios
Feature Development
# Setup
mkdir user-profile-feature && cd user-profile-feature
git init
# Commit 1: Database schema
echo "CREATE TABLE users (id, name, email);" > schema.sql
git add schema.sql
git commit -m "Add user profile database schema"
# Commit 2: API endpoints
echo "class UserAPI { getProfile() {...} }" > user-api.js
git add user-api.js
git commit -m "Add user profile API endpoints"
# Commit 3: Frontend component
echo " " > UserProfile.jsx
git add UserProfile.jsx
git commit -m "Add user profile React component"
# Commit 4: Tests
echo "test('user profile loads', () => {...})" > profile.test.js
git add profile.test.js
git commit -m "Add tests for user profile feature"
Bug Fix Workflow
# Commit 1: Add test that reproduces the bug
echo "test('login fails with special chars', () => {...})" > login.test.js
git add login.test.js
git commit -m "Add test for login bug with special characters"
# Commit 2: Fix the bug
echo "function sanitizeInput(input) { return input.replace(/[^a-zA-Z0-9]/g, ''); }" > auth.js
git add auth.js
git commit -m "Fix login validation to handle special characters
The login function was failing when usernames contained special
characters like @ or -. Added input sanitization while preserving
valid email addresses.
Fixes #Bug-456"
Commit History and Information
Viewing Commits
# Basic log
git log
# One-line format
git log --oneline
# Graph view with branches
git log --oneline --graph --all
# Show files changed
git log --stat
# Show actual changes
git log -p
# Last 5 commits
git log -5
# Commits by author
git log --author="John Doe"
# Commits in date range
git log --since="2023-10-01" --until="2023-10-31"
Commit Details
# Show specific commit
git show a1b2c3d
# Show commit with stats
git show --stat a1b2c3d
# Show just the message
git log --format="%B" -n 1 a1b2c3d
Commit Best Practices
Atomic Commits
- ✅ One feature per commit
- ✅ One bug fix per commit
- ✅ Related changes together
- ❌ Don't mix features and fixes
- ❌ Don't commit broken code
Commit Testing
# Run tests
npm test
# or
python -m pytest
# or
make test
# Only commit if tests pass
git add .
git commit -m "Add user validation feature"
Commit Frequency
- ✅ Commit often: Small commits are easier to understand and revert
- ✅ Commit complete work: Don't commit half-implemented features
- ✅ Commit before risky changes: Create safe points
- ❌ Don't commit every keystroke: Balance frequency with meaning
Working with Commit History
Finding Commits
# Search commit messages
git log --grep="user auth"
# Search code changes
git log -S"function login"
# Find when file was added
git log --follow -- filename.js
# Show branch history
git log --oneline --graph main..feature-branch
Commit Statistics
# Count commits
git rev-list --count HEAD
# Commits per author
git shortlog -sn
# Activity by date
git log --format="%ad" --date=short | sort | uniq -c
# Files changed most often
git log --format="" --name-only | sort | uniq -c | sort -rg
Common Commit Mistakes
Fixing Commit Mistakes
git commit --amend -m "Correct message"
git add missing-file.txt
git commit --amend --no-edit
# Undo last commit, keep changes
git reset --soft HEAD~1
# Make more changes
echo "more code" >> file.txt
git add file.txt
# Commit again
git commit -m "Complete feature implementation"
Commit Message Anti-Patterns
- Vague messages: "fix", "update", "changes"
- Past tense: "Fixed bug" (use "Fix bug")
- Implementation details: "Changed for loop to while loop"
- Multiple unrelated changes in one commit
- Committing commented-out code
Team Commit Conventions
Setting Up Team Standards
# Create project template
cat > .gitmessage << EOF
[TICKET-ID] Brief description
* What changed
* Why it changed
* Any breaking changes
Co-authored-by: Team Member
EOF
# Configure for this repository
git config commit.template .gitmessage
Commit Hooks for Quality
#!/bin/sh
# .git/hooks/pre-commit
# Run tests before allowing commit
npm test
if [ $? -ne 0 ]; then
echo "Tests failed. Commit aborted."
exit 1
fi
# Check commit message format
commit_msg_file=$1
commit_msg=$(cat $commit_msg_file)
if ! echo "$commit_msg" | grep -qE "^(feat|fix|docs|style|refactor|test|chore)\(.*\):"; then
echo "Invalid commit message format. Use conventional commits."
exit 1
fi
Summary
You now understand Git commits:
- ✅ Commits are permanent snapshots with metadata
- ✅ Good commit messages follow the seven rules
- ✅
git commit --amend
fixes recent commits - ✅ Atomic commits make history easier to understand
- ✅ Test before committing to maintain quality
- ✅ Use templates and conventions for consistency
- ✅
git log
has many options for exploring history
Next Steps
Now that you can create great commits, let's learn how to view and understand your project's history: