Where your changes live: add, commit, status, diff

The mental model everything else builds on · 9 min

In one breath

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 ─────────────────────────────────
PlaceWhat's thereWho sees it
Working treeThe files you're editing right nowOnly you, and not saved in git yet
Staging area (a.k.a. the index)The changes you've picked for the next commitOnly you
Local repoEvery commit you've made, in .git/Only you, until you push
Remote (origin)The shared copy, e.g. github.com/guymellsop/WadOfGoreEveryone 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

CommandDoes
git statusWhat's changed, and what's staged. Run it constantly. It's free.
git add Source/.../WarriorAbilitySystemComponent.cppStage one file
git add -pGo through changes piece by piece and choose y/n for each. The best way to split work into clean commits.
git add -AStage everything. Fast, but check status first so you don't commit junk.
git commit -m "Message"Save the staged changes as a commit
git diffChanges not yet staged (working tree vs staging)
git diff --stagedChanges that are staged: exactly what the next commit will contain. Read this before committing.
git diff HEAD~1Everything changed since one commit ago
git log --onelineHistory, one line per commit
git show 5960ce1What 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

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

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.