Staging & Commits
Master the add-commit workflow — stage changes precisely and write commits your team will thank you for
You now know Git records snapshots. This lesson is about doing it well: staging exactly the right changes and writing commit messages that make your history readable months later.
The Add–Commit Loop
Day-to-day Git is a loop: edit files, stage what belongs together, commit with a message, repeat.
git add <files> # stage changes for the next commit
git status # verify what's staged
git commit -m "..." # record the snapshot
The skill is in the git add step — grouping related changes into one focused commit instead of one giant "did stuff" commit.
Staging Precisely
git add is more flexible than "add everything". You control the granularity:
git add file.txt # one specific file
git add src/ # everything under a directory
git add . # everything in the current directory tree
git add -A # every change in the repo (incl. deletions)
To see the difference between what's staged and what's still unstaged:
git diff # unstaged changes (working dir vs staging)
git diff --staged # staged changes (staging vs last commit)
git add -p walks you through each change ("hunk") and asks whether to
stage it. It's the pro move for splitting unrelated edits in the same file
into separate, clean commits.
Undoing Staging (Safely)
Staged something by mistake? Unstage it — this keeps your edits, it only removes them from the staging area:
git restore --staged file.txt # unstage, keep the edit
Want to throw away the edits in your working directory entirely? This is destructive — the changes are gone:
git restore file.txt # discard unstaged edits (careful!)
working dir ──restore──▶ (edits discarded)
staging ──restore --staged──▶ working dir (edits kept, just unstaged)
git restore file.txt permanently deletes uncommitted changes to that file.
Unlike almost everything else in Git, this cannot be recovered. When unsure,
commit or stash first.
Anatomy of a Good Commit
A commit does two things: it snapshots your code, and it explains the change. The message is documentation your future teammates (and future you) will read constantly.
This project follows Conventional Commits — a simple, structured format:
<type>(<scope>): <description>
[optional body explaining what and why]
Common types: feat (new feature), fix (bug fix), docs, refactor, test, chore.
git commit -m "feat(auth): add password reset flow"
git commit -m "fix(ui): correct button alignment on mobile"
The rules that matter most:
| Rule | Bad | Good |
|---|---|---|
| Imperative mood | added login | add login |
| Lowercase, no period | Fix bug. | fix: handle empty input |
| Explain why in the body | (nothing) | "Users hit a 500 when the cart was empty" |
Why bother? Structured messages give you auto-generated changelogs, readable history, and easy filtering:
git log --oneline --grep "^feat" # show only features
A Complete Example
# You edited two unrelated things: a feature and a typo fix.
git add src/login.ts
git commit -m "feat(auth): add remember-me checkbox"
git add README.md
git commit -m "docs: fix typo in setup steps"
Two focused commits instead of one muddled one. When someone later runs git log, the story of the project is clear.