Interactive: the Git state simulator
Beginner Core Git
Why this matters
Reading about areas and pointers is one thing; watching them move is another. The simulator below runs a small model of Git inside the page. Type commands, watch files move between the working tree, the staging area and the repository, and see branch labels slide along the commit graph. Nothing you do here touches a real repository, so try anything.
The simulator
The Git state simulator loads here.
The simulator understands the everyday commands (init, status, add, commit, log, diff, branch, switch, checkout, merge without conflicts, tag, stash, reset, revert, and fetch, pull, push against a pretend remote), plus edit <file> "text" and touch <file> to change files, and help. It prints realistic output and draws the four areas and the graph after every command. The Guided button walks through the sequence below with an explanation at each step.
The same walk, written out
If the simulator is not loaded (for example on a printed page), the guided sequence is this. Each step names the command and the state of the areas afterwards.
git init. Working tree: empty. Staging area: empty. Repository: no commits; a branchmainthat points nowhere yet; HEAD attached to it.touch README.md(create a file). Working tree:README.mduntracked. Nothing else changes.git add README.md. Staging area:README.md(new). The working tree is unchanged.git commit -m "Add README". Repository: commit C1 containingREADME.md;mainpoints at C1; HEAD → main → C1. Staging area matches C1.git status: clean.edit README.md "Hello", thengit status. Working tree:README.mdmodified. Staging area: still C1's version. Status reports "Changes not staged".git add README.md,git commit -m "Greet". Repository: C2 with parent C1;main→ C2.git switch -c docs/12-guide. A new labeldocs/12-guideat C2; HEAD now points at it. No files change.touch guide.md,git add guide.md,git commit -m "Add guide". C3 with parent C2;docs/12-guide→ C3;mainstill → C2.git switch main. HEAD → main → C2. The working tree is rewritten to C2's snapshot:guide.mddisappears (it is safe in C3).git merge docs/12-guide. Fast-forward:mainsimply moves to C3, because C3 is a direct descendant of C2.guide.mdis back.git tag v1.0. A tag label at C3. It will never move.edit README.md "Hello again",git add README.md,git commit -m "Update greeting". C4;main→ C4;v1.0stays at C3.git revert HEAD. A new commit C5 whose content undoes C4;main→ C5. History is added to, not rewritten.git reset --soft HEAD~1.mainmoves back to C4; C5 is no longer on any branch; its changes sit in the staging area. This is the first rewriting command in the walk, and it is safe only because nothing was pushed.git push -u origin main. The pretend remote receives C1 to C4;origin/main→ C4;mainis now a tracking branch. Status: up to date.git stash, after editing a file: the edit leaves the working tree and waits in the stash;git stash popbrings it back.
Every later section of the course is a variation of these sixteen moves.
Try it yourself
Goal: predict, then check.
- In the simulator, run steps 1 to 9 of the walk. Before step 9, write down which files you expect to see in the working tree afterwards.
- Run step 9 and compare.
- Run steps 10 to 12, then
git log --oneline --decorate, and identify which labels point at which commits before reading the output.
Expected result: after step 9, guide.md is absent (it exists only in C3, which main does not include yet); after step 12, main and HEAD are at C4 and v1.0 is at C3.
Show solution
Switching branches makes the working tree match the branch's commit. main at C2 has no guide.md. After the fast-forward merge and two more commits, main has moved twice while the tag stayed put: tags name a moment, branches name a line of work.