The Staging Area – Why It Exists
Git tracks your files across three distinct zones:
| Zone | Also called | What lives here |
|---|---|---|
| Working directory | Working tree | Your actual files on disk — edited freely |
| Staging area | Index, cache | Changes you've explicitly selected for the next commit |
| Repository | .git database | Permanent commit history, stored in .git/objects/ |
The staging area lets you craft precise commits. Imagine you fixed a bug and reformatted some unrelated code. Without staging, you'd have to commit everything together. With staging, you can add only the bug-fix files and commit them separately from the reformatting — resulting in a cleaner, more reviewable history.
Every commit in Git gets a unique 40-character hexadecimal fingerprint called a SHA-1 hash (or commit ID), e.g. a3f8c2d1.... It is calculated from the commit's contents, author, timestamp, and parent commit — so it is effectively unique. You only need to type the first 7 characters when referencing a commit in commands.
git add – Staging Changes
The git add command moves changes from the working directory into the staging area. You can be as specific or as broad as you like.
Stage a specific file
# Stage a single file
git add README.md
# Stage a file in a subdirectory
git add src/main.py
# Stage multiple specific files
git add index.html style.css
Stage everything in the current directory
# Stage ALL changes (new files, modifications, deletions) recursively
git add .
# Alternative: stage everything from the repo root, regardless of where you are
git add -A
Running git add . stages everything — including temporary files, build artifacts, and secrets you may not want in version control. Always check git status before committing and keep a good .gitignore file to exclude files you never want tracked.
Stage changes interactively (patch mode)
git add -p is one of the most powerful staging tools. It walks through every changed hunk (a continuous block of changes) in your files and asks whether you want to stage it. This lets you split a single file's changes across multiple commits.
# Launch interactive patch mode
git add -p
# Or for a specific file
git add -p src/main.py
@@ -10,7 +10,9 @@ def calculate():
result = a + b
+ # New: validate inputs
+ if a < 0 or b < 0:
+ raise ValueError("Inputs must be positive")
return result
Stage this hunk [y,n,q,a,d,s,?]?
Key responses: y stage this hunk, n skip it, s split into smaller hunks, q quit, ? show help.
git commit – Saving the Snapshot
Once your changes are staged, git commit saves them as a permanent snapshot in the repository's history. Every commit records: what changed, who made the change, when, and a message explaining why.
Commit with an inline message
# Commit staged changes with a short message
git commit -m "Add input validation to calculate function"
[main a3f8c2d] Add input validation to calculate function
1 file changed, 3 insertions(+)
Git shows the branch name, the first 7 characters of the new commit's SHA, the message, and a summary of what changed.
Commit with a multi-line message (opens your editor)
# Opens your configured editor (usually vim, nano, or VS Code)
git commit
# Configure VS Code as your commit editor
git config --global core.editor "code --wait"
Writing Good Commit Messages
A good commit message is a gift to your teammates — and to your future self six months from now. The widely-adopted convention:
Short summary in imperative mood (50 chars max)
Optional longer body explaining WHY this change was made,
what problem it solves, and any context reviewers need.
Wrap lines at ~72 characters.
Optionally reference issue numbers:
Closes #123
| Bad message | Good message |
|---|---|
fix | Fix null pointer crash when user has no profile photo |
wip | Add skeleton for user authentication module |
updated stuff | Update API base URL to use environment variable |
fixing the thing | Correct off-by-one error in pagination calculation |
Think of the subject line as completing the sentence: "If applied, this commit will...". So: "If applied, this commit will Add input validation" — not "Added input validation".
git commit --amend – Editing the Last Commit
Made a typo in your last commit message? Forgot to stage one file? --amend lets you rewrite the most recent commit.
# Fix the last commit message only
git commit --amend -m "Add input validation with proper error messages"
# Add a forgotten file to the last commit
git add forgotten-file.py
git commit --amend --no-edit # --no-edit keeps the original message
--amend rewrites the commit — it creates a brand-new commit with a different SHA and discards the old one. If you've already pushed to a shared branch and then amend, your local history diverges from the remote. Other team members who pulled the original commit will get conflicts. Rule of thumb: amend only your local, unpushed commits.
Checking What You've Committed
After committing, confirm everything looks right:
# See recent commits
git log --oneline -5
# Check current staging status
git status
a3f8c2d (HEAD -> main) Add input validation to calculate function
7b9e1a3 Initial project setup
On branch main
nothing to commit, working tree clean
"Nothing to commit, working tree clean" is the green light — all changes are committed and the staging area is empty.
📋 Summary
- Git has three zones: working directory (edited files), staging area (selected for next commit), and the repository (permanent history).
- git add <file> — stage a specific file;
git add .stages everything (use carefully). - git add -p — interactive patch mode; stage individual hunks within a file for precise commits.
- git commit -m "message" — create a commit with an inline message.
- Good commit messages: imperative mood, 50-char subject, explain the why in the body.
- git commit --amend — rewrite the last commit (message or content); only safe before pushing.
- Every commit gets a unique SHA hash — the first 7 characters are enough for most commands.
FAQ
Git will show the message nothing to commit, working tree clean (if no changes exist) or nothing added to commit but untracked files present (if you have new files but haven't staged them). No commit is created. You must run git add first to stage changes before git commit will do anything.
Yes — for already-tracked files only: git commit -a -m "message" (or git commit -am "message") stages all modifications to tracked files and commits them in one step. It does not stage new (untracked) files. While convenient, skipping the explicit git add step means you lose the ability to selectively stage changes, so use it only when you're sure you want to commit everything.
Use git restore --staged <file> (Git 2.23+) to unstage a file without discarding your changes — the file goes back to "modified but not staged". The older equivalent is git reset HEAD <file>. Your actual file content is untouched either way; only the staging area entry is removed.
The subject line should be 50 characters or fewer (GitHub truncates at 72). For simple changes, a one-liner is fine. For anything non-obvious — a complex bug fix, an architectural decision, a workaround — add a body after a blank line. The body should explain why the change was made, not just what changed (the diff already shows the what). There is no strict maximum for the body length.