Where your changes live: add, commit, status, diff
A change moves through four places: your files on disk (working tree) → a "next commit" tray
(staging area) → your local history (commits) → GitHub (remote). add moves changes onto the
tray, commit saves the tray as a snapshot, push sends snapshots to GitHub. status and
diff tell you what's where.
The four places
working tree ──add──▶ staging area ──commit──▶ local repo ──push──▶ remote (GitHub)
(files on disk) ("the tray") (your commits) (origin)
◀──────────────────────────────── pull ─────────────────────────────────
| Place | What's there | Who sees it |
|---|---|---|
| Working tree | The files you're editing right now | Only you, and not saved in git yet |
| Staging area (a.k.a. the index) | The changes you've picked for the next commit | Only you |
| Local repo | Every commit you've made, in .git/ | Only you, until you push |
Remote (origin) | The shared copy, e.g. github.com/guymellsop/WadOfGore | Everyone on the team |
Blueprint analogy: the working tree is your unsaved editor. Staging is ticking which assets go in the save dialog. A commit is pressing Save, but every save is kept forever, with a note.
Why have a staging area at all?
So one commit can be one idea. Say you fixed the include order and started the unequip ability. Stage only the include fix, commit it ("Put each .cpp's own header first"), then commit the unequip work separately. Each commit can then be understood, reviewed, or undone on its own. Teams care a lot about this.
The commands
| Command | Does |
|---|---|
git status | What's changed, and what's staged. Run it constantly. It's free. |
git add Source/.../WarriorAbilitySystemComponent.cpp | Stage one file |
git add -p | Go through changes piece by piece and choose y/n for each. The best way to split work into clean commits. |
git add -A | Stage everything. Fast, but check status first so you don't commit junk. |
git commit -m "Message" | Save the staged changes as a commit |
git diff | Changes not yet staged (working tree vs staging) |
git diff --staged | Changes that are staged: exactly what the next commit will contain. Read this before committing. |
git diff HEAD~1 | Everything changed since one commit ago |
git log --oneline | History, one line per commit |
git show 5960ce1 | What one commit changed |
The trap: plain git diff shows nothing for changes you've already added. That's not
because they're gone. They're staged. Use --staged.
What a commit actually is
- A snapshot of the whole project at that moment (git stores it efficiently, only what changed).
- Plus: author, date, message, and a pointer to its parent commit (the one before it).
- Identified by a hash like
5960ce1253c5…, usually shortened to the first 7 characters. The hash is calculated from the contents, so a commit can never be secretly changed. Change anything and it's a new hash.
Writing good commit messages
Your WadOfGore history already does this well:
fa176d1 Add weapon registration to pawn combat component
403f1fc Add ability input binding and hero startup ability sets
- Imperative mood: "Add…", "Fix…", not "Added…". Read it as "this commit will add…".
- First line short (~50–70 characters). It's what
log --onelineand GitHub show. - Body (optional) explains why, after a blank line. The diff already shows what.
- Avoid "fixes", "wip", "stuff". Six months later, in a team, nobody (including you) knows what they meant.
Quiz yourself
Name the four places a change moves through, in order.
Working tree → staging area → local repo (commits) → remote.
What's the staging area for?
Choosing exactly what goes into the next commit, so each commit is one idea even if you changed several things.
You git add a file and git diff shows nothing. Why, and what shows it?
Plain git diff only shows unstaged changes. git diff --staged shows staged ones.
What does git add -p do?
Walks through your changes hunk by hunk and lets you stage only some, for splitting work into clean commits.
After git commit, can your team see it?
No. It's only in your local repo until you git push.
What is a commit hash, and why can't a commit be quietly edited?
An ID calculated from the commit's contents and parent. Changing anything produces a different hash, i.e. a different commit.
Rewrite "fixed stuff with weapons" as a good commit subject.
Something like "Fix crash when the equipped weapon is destroyed". Imperative, specific, short.