open atlas
↑ Back to track
Git, from zero to senior GIT · 01 · 03

The three areas

Every change sits in one of three areas: the working tree (files you edit), the staging area/index (the proposed next commit), and the repository (history in .git). git add stages, git commit writes the index and moves HEAD, git status maps where each change is.

GIT Foundations ◷ 16 min
Level
FoundationsJuniorMiddleSenior

Newcomers learn git add then git commit as a two-word incantation and never ask why there are two steps. Other tools just have “save.” That extra step is git’s single most distinctive idea, and once you see what it is for, a whole class of confusing messages — “changes not staged for commit”, “changes to be committed” — suddenly reads like plain English.

By the end of this lesson you will be able to name the three places a file can live in git, say which command moves a change from one to the next, and read git status as a map of exactly where each of your changes currently sits.

Goal

After this lesson you can name git’s three areas — working tree, staging area (index), and repository — explain that git add stages and git commit records, describe what HEAD points to, and read a git status output as a map of which area each change is in.

1

A tracked file’s change can be in one of three areas. Think of it as three rooms a change passes through:

  • The working tree (or working directory) — the actual files on disk you open and edit. This is where you make changes.
  • The staging area, also called the index — a holding zone describing the proposed next commit. A change here is marked “this will go into my next commit.”
  • The repository — the committed history stored in .git. Once a change is committed, it is permanent history (see the previous lesson: a snapshot).

A change moves working tree → staging → repository, one explicit command per hop.

2

git add copies a change from the working tree into the staging area. It does not commit anything; it marks which changes you intend to include next.

git add app.js          # stage one file's current changes
git add .               # stage every change in this directory tree

A subtlety worth internalizing early: git add stages a snapshot of the file as it is right now. If you edit app.js again after staging it, that newer edit is not staged — the index still holds the version from the moment you ran add. The working tree and the index can hold two different versions of the same file at once.

3

git commit writes whatever is in the staging area as a new commit, and moves HEAD. Commit takes the staged snapshot — not the working tree — and records it as a permanent commit in the repository.

git commit -m "Add login form"

HEAD is git’s pointer to “where you are now” — the commit your next commit will build on top of. After a successful commit, the new commit becomes the latest in history and HEAD advances to point at it. Anything you changed but did not stage is untouched by the commit and stays as a pending change in the working tree.

4

git status shows which area every change is in. It is the map that ties the three areas together. It sorts your changes into three buckets:

git status
# Changes to be committed:        <- staged (in the index)
# Changes not staged for commit:  <- edited in working tree, not yet added
# Untracked files:                <- new files git has never seen

Read literally: “to be committed” = staged, “not staged” = working-tree edits awaiting git add, “untracked” = files that exist on disk but were never added to git at all. Run it constantly; it removes all guessing about what your next commit will contain.

Why this works

Why have a staging area at all instead of committing the working tree directly? Because it lets you craft a commit from a subset of your changes. Suppose you fixed a bug and, while in there, also reformatted an unrelated file. Those should be two commits, not one muddled one. The index lets you stage only the bug fix, commit it cleanly, then stage and commit the formatting separately. The sharpest tool for this is patch mode:

git add -p     # interactively stage selected hunks, not whole files

git add -p walks you through each changed hunk and asks whether to stage it — so even parts of one file can go into different commits. The staging area is what makes a tidy, reviewable history possible instead of dumping every in-progress edit into one lump.

Worked example

Two edits, one clean commit.

You open a repo and change two files: you fix a real bug in auth.js and you also tweak indentation in README.md. You only want the bug fix in this commit.

  1. git status shows both under Changes not staged for commit — edited in the working tree, nothing staged yet.
  2. git add auth.js promotes only the bug fix into the staging area. Run git status again: auth.js now appears under Changes to be committed, while README.md stays under Changes not staged for commit. The two files are now in two different areas.
  3. git commit -m "Fix token refresh bug" writes the staged snapshot — just auth.js — as a new commit, and HEAD advances to it. The README change is not in the commit; it is still a pending edit in the working tree, ready for its own separate commit later.

The staging area is exactly what let you split one working session into a precise, single-purpose commit.

Common mistake

The classic trap: you git add file.js, then keep editing file.js, then git commit and expect your latest edits to be in. They are not. add captured the file as it was at that instant; the edits you made afterward live only in the working tree. The fix is to git add again before committing (or use git commit -a, which auto-stages changes to already-tracked files — but note it skips untracked files entirely). When in doubt, git status before every commit tells you precisely what is staged.

Check yourself
Quiz

You edit app.js, run git add app.js, then edit app.js again, then run git commit. What ends up in the commit?

Recap

A change in git lives in one of three areas: the working tree (files you edit on disk), the staging area / index (the proposed next commit), and the repository (committed history in .git). git add promotes a change from the working tree into the index — capturing the file as it is at that instant — and git commit records the staged snapshot as a new commit, advancing HEAD to point at it. git status is the map: “to be committed” is staged, “not staged” is working-tree edits awaiting add, “untracked” is files git has never seen. The staging area exists so you can craft a focused commit from a subset of your changes, down to individual hunks with git add -p. Next you will install git, set your identity, and create your very first repository.

Practice

Start at the top. Tasks go easiest → hardest: recall a fact, apply it to a case, then a senior-level stretch. Open one, attempt it, then reveal.

recallapplystretch0 of 4 done

Something unclear?

Ask a question about this lesson. Questions are anonymous and go straight to the author to make the lesson better.

shortcuts expand
search
K
prev piece
k
next piece
j
cycle tier
t
this menu
?
sources2
expand
  1. 01
  2. 02

Trademarks belong to their respective owners. Editorial reference only.