Gitastic
Path › Part 1: The mental model › Lesson 2 of 16
02

The three areas

Working directory → staging area → repository. Where your changes actually live.

1 Learn the idea

Ever wondered why git makes you add before you commit? It is because your changes pass through three places, and most everyday commands just move files between them.

The three areas

  • Working directory — the real files in your folder. You edit here. Git watches, but does not save anything yet.
  • Staging area (also called the index) — the draft of your next commit. It is a full snapshot too, not just a list of changes.
  • Repository — the commits. HEAD points at the one you are standing on; its snapshot is what the other two are compared against.

2 Watch it happen

Move changes between the areas

Press Play or use → to step through. Watch the graph as each command runs.

e80d012 Start sitee80d012Start site472f2f2 Add styles472f2f2Add stylesHEAD = where you are. It points at the current branch.HEAD →Branch "main" — a movable pointer (current branch: moves when you commit)main
Working directoryyour folder / editor
index.html
style.css
git add →← git restore
Staging areathe next snapshot (index)
index.html
style.css
git commit →← restore --staged
RepositoryHEAD → 472f2f2
index.html
style.css
terminal · simulated, no real repository is touched
Read this demo as text
  1. $ git status

    All three areas agree: the working directory, the stage and the last commit hold the same snapshot. "Working tree clean".

  2. $ edit index.html "<h1>Hello, friend!</h1>"
    $ edit style.css "h1 { color: tomato }"

    We edit two files. Only the working directory changes — the stage and the repository still hold the old versions.

  3. $ git status

    git status compares the areas for you: two files are modified but "not staged for commit".

  4. $ git diff

    Plain git diff shows working directory vs. staging area: what you changed but have not staged yet.

  5. $ git add index.html

    We stage just index.html. Watch it move onto the stage — style.css stays behind in the working directory.

  6. $ git diff --staged

    git diff --staged shows staging area vs. last commit: exactly what the next commit will contain.

  7. $ git restore style.css

    We decide the tomato colour was a bad idea. git restore <file> overwrites the working copy with the staged version. Careful: those edits are gone, not saved anywhere.

  8. $ git commit -m "Friendlier greeting"

    Click. The commit is made from the stage, not from your folder. All three areas agree again.

  9. $ echo "remember the footer" > todo.txt
    $ git add todo.txt
    $ git restore --staged todo.txt

    Staged something by accident? git restore --staged <file> takes it off the stage but keeps your file. todo.txt is back to untracked.

  10. $ git status

    Untracked files are ones git has never been told about. They are never committed until you git add them.

Command
  • git add <file>
  • git restore --staged <file>
  • git restore <file>
  • git commit
What moves
  • working directory → stage
  • last commit → stage (unstage)
  • stage → working directory (discard edits!)
  • stage → new commit in the repository
git statusWhich files differ between the three areas
git diff [--staged]Unstaged changes (or, with --staged, what the next commit holds)
git restore [--staged] <file>Discard edits (or unstage, keeping the file)
git commit -am "msg"Stage all tracked changes and commit

3 Check your understanding

Question 1

Look at the three areas. If you run git commit -m "Update" right now, what ends up in the new commit?

c05020b Initc05020bInita6083b4 Add ba6083b4Add bHEAD = where you are. It points at the current branch.HEAD →Branch "main" — a movable pointer (current branch: moves when you commit)main
Working directoryyour folder / editor
a.txt
b.txtchanged
git add →← git restore
Staging areathe next snapshot (index)
a.txtchanged
b.txt
git commit →← restore --staged
RepositoryHEAD → a6083b4
a.txt
b.txt
Question 2

You run git add app.js, then edit app.js again, then git commit. What gets committed?

Question 3

git status says "Changes to be committed", but git diff prints nothing. Why?

Question 4

Which command permanently throws away your uncommitted edits to notes.md?

4 Practice for real

Your mission

The focused commit

You built a search feature in app.js, but also left a red debug border in style.css and a debug.log file. Make one commit containing only the app.js change, discard the style.css debug edit, and leave debug.log untracked (do not delete it).

97236a3 Create app click to insert the hash into the terminal97236a3Create appf821aeb Add styles click to insert the hash into the terminalf821aebAdd stylesHEAD = where you are. It points at the current branch.HEAD →Branch "main" — a movable pointer (current branch: moves when you commit)main
Working directoryyour folder / editor
app.jschanged
debug.lognew
style.csschanged
git add →← git restore
Staging areathe next snapshot (index)
app.js
style.css
git commit →← restore --staged
RepositoryHEAD → f821aeb
app.js
style.css
terminal · simulated, no real repository is touched
Type commands below. `help` lists everything. Tab completes, ↑ recalls. Click a commit to paste its hash.
~/project (main) $