Git - Committing

Beginner

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"
Expected Output:
[main a1b2c3d] Update project description
 1 file changed, 3 insertions(+), 1 deletion(-)

Commit with Editor

Open editor for longer message:
git commit

This opens your configured editor with a template:

Editor content:

# 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

Skip staging for 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

  1. Separate subject from body with blank line
  2. Limit subject line to 50 characters
  3. Capitalize the subject line
  4. Don't end subject line with period
  5. Use imperative mood ("Add" not "Added")
  6. Wrap body at 72 characters
  7. Use body to explain what and why, not how

Good Examples

✅ Simple commit:
git commit -m "Add user registration form"
✅ Detailed commit:
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

❌ Poor commit messages:
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

Create commit message 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
Configure Git to use template:
git config --global commit.template ~/.gitmessage

Conventional Commits

Many teams use standardized commit formats:

Conventional commit format:
type(scope): description

[optional body]

[optional footer(s)]
Examples:
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:

Change last commit message:
git commit --amend -m "Better commit message"
Add files to last commit:
git add forgotten-file.txt
git commit --amend --no-edit
Warning: Only amend commits that haven't been pushed yet. Amending changes the commit ID.

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

Breaking down a feature into commits:
# 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

Systematic bug fix approach:
# 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

Make each commit do one thing well:
  • ✅ 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

Test before committing:
# 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

Wrong commit message:
git commit --amend -m "Correct message"
Forgot to add files:
git add missing-file.txt
git commit --amend --no-edit
Committed too early:
# 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

❌ Avoid these 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

Project-specific commit template:
# 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

Pre-commit hook example:
#!/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:

Git - Status & Inspection

Practice Tip: Create a practice repository and experiment with different commit styles. Try amending commits and using the log commands to explore your history.