git add & git commit — Staging and Saving Changes
Module 01 60 min
Section Objectives
- Master the staging area with
git add - Create meaningful commits with
git commit - Write professional commit messages
- Use interactive staging for precise commits
The Staging Area in Detail
The staging area (also called the index) is Git's unique superpower compared to older version control systems. It lets you build your commit with surgical precision.
Why Does the Staging Area Exist?
Imagine you've spent the morning working on a feature. You've modified 5 files. But you realize:
- 3 files belong to one feature
- 2 files are a bug fix
Without a staging area, you'd have to commit everything together. With the staging area, you can create 2 separate, logical commits.
git add Variants
Basic Commands
# Add a specific file
git add README.md
# Add an entire folder
git add src/
# Add all changes in current directory
git add .
# Add all tracked files (including deleted files)
git add -A
# Add only modified/deleted files (not new)
git add -u
Interactive Staging — The Most Powerful Option
# Choose exactly what to stage, line by line
git add -p # or --patch
# Git shows each "hunk" (code block) and asks:
# y = yes (stage this hunk)
# n = no (skip this hunk)
# s = split (split into smaller hunks)
# e = edit (manually edit what gets staged)
# q = quit
Example session with git add -p:
diff --git a/main.py b/main.py
index a1b2c3d..e4f5g6h 100644
--- a/main.py
+++ b/main.py
@@ -1,5 +1,8 @@
def greet(name):
return f"Hello, {name}!"
+def farewell(name): # ← new function
+ return f"Goodbye, {name}!"
+
def calculate(a, b):
return a + b
Stage this hunk [y,n,q,a,d,/,e,?]?
Why use
git add -p?Interactive staging is a professional's best practice. It creates small, focused commits that are easy to review, revert, or understand in 6 months. Commit history becomes true documentation.
git commit Variants
Basic Commands
# Commit with a message in one line
git commit -m "feat: add user login feature"
# Commit with a detailed description (opens editor)
git commit
# Stage all tracked files AND commit in one step
git commit -am "fix: correct calculation bug"
# Amend the last commit (before pushing!)
git commit --amend -m "New corrected message"
git commit --amend --no-edit # Keep the message, add new staged files
Viewing What You're About to Commit
# View unstaged changes (working tree vs staging area)
git diff
# View staged changes (staging area vs last commit)
git diff --staged # or: git diff --cached
# Summary of what will be committed
git status
Writing Professional Commit Messages
A good commit message answers: "What does this commit DO and WHY?"
The Conventional Commits Format
<type>(<optional scope>): <description>
[optional body]
[optional footer]
Commit Types
| Type | Use Case | Example |
|---|---|---|
feat | New feature | feat: add user registration |
fix | Bug fix | fix: correct email validation regex |
docs | Documentation only | docs: update API documentation |
style | Formatting, no logic change | style: format code with prettier |
refactor | Refactoring, no new feature | refactor: extract auth helper function |
test | Adding or fixing tests | test: add unit tests for login |
chore | Maintenance, config, build | chore: update dependencies |
perf | Performance improvement | perf: optimize database query |
ci | CI/CD configuration | ci: add GitHub Actions workflow |
revert | Revert a commit | revert: revert "feat: add login" |
Good vs Bad Commit Messages
# ❌ BAD — what does this do?
git commit -m "fix"
git commit -m "changes"
git commit -m "WIP"
git commit -m "asdfgh"
# ✅ GOOD — clear and descriptive
git commit -m "feat(auth): add JWT token refresh mechanism"
git commit -m "fix(api): handle 404 response for missing user"
git commit -m "docs: add setup instructions to README"
git commit -m "chore: upgrade dependencies to latest versions"
Multi-line Commit with Body
git commit
# Opens your editor. Write:
feat(checkout): add Stripe payment integration
Replace the previous PayPal integration with Stripe for:
- Lower transaction fees (2.9% vs 3.5%)
- Better international card support
- Real-time webhook notifications
Closes #142
Reviewed-by: Bob Martin
Understanding File States
A file in Git can be in one of several states:
| State | Description | Command to view |
|---|---|---|
| Untracked | New file, Git doesn't know about it | git status |
| Modified | Tracked file with unsaved changes | git diff |
| Staged | Ready to be committed | git diff --staged |
| Committed | Saved in the repository | git log |
| Ignored | Excluded via .gitignore | git status --ignored |
Practical Examples
Scenario 1: Feature + Bug Fix in Same Session
# You've worked on 2 things today
git status
# Modified: src/auth/login.py ← new feature
# Modified: src/auth/register.py ← new feature
# Modified: src/utils/email.py ← bug fix
# Commit the bug fix separately
git add src/utils/email.py
git commit -m "fix(utils): correct email normalization for uppercase"
# Commit the new feature
git add src/auth/
git commit -m "feat(auth): add login and registration endpoints"
Scenario 2: Partial Staging with -p
# You modified a file but only want to commit part of it
git add -p src/main.py
# Git shows each block of changes
# Stage only the relevant blocks
# Leave unfinished blocks unstaged
Summary of Key Commands
| Command | Description |
|---|---|
git add <file> | Stage a specific file |
git add . | Stage all changes |
git add -p | Interactive staging |
git commit -m "msg" | Commit with message |
git commit -am "msg" | Stage all + commit |
git commit --amend | Modify last commit |
git diff | View unstaged changes |
git diff --staged | View staged changes |
git status | View current state |