Git Commands, HEAD & Refs (Visual)

Lab
Easy
Medium
Hard

Your first commitsEasy

Working directory → staging area → repository, one arrow at a time.

terminalclick a line to jump to it
$
Click to add a command

Commands run on a safe in-browser simulator. edit <file> simulates changing a file.

1 / 10
Start
A fresh repository with one commit on main. HEAD points at the main label, which points at the latest commit. Step forward to watch each command change the picture.

The three areas

HEAD → main
Working directory
  • README.mdv1
git add
Staging area (index)
  • README.mdv1
git commit
Repository @ HEAD
  • README.mdv1
← switch / checkout / reset --hard rewrites the working directory modified, not staged staged

Commits, branches and HEAD

branch HEAD tag origin/…
a1b2c3d Initial commita1b2c3dInitial commitmainHEAD

Arrows point from a commit to its parent (history reads right-to-left). Dashed circles are commits no branch can reach any more (or that exist only on the remote).

What this command changed

No branch, tag or remote label moved.

Learn the theory

Git Commands, HEAD & Refs (Visual): how it works

5 min read · Updated

Git feels mysterious until you see its three moving parts: three areas that files travel between, a graph of commits, and a handful of pointers — branches, tags and HEAD — that label spots on that graph. Every Git command either moves files between the areas, adds commits to the graph, or moves a pointer. This lab lets you run the commands and watch exactly which of those three things happens.

In short

  • Files flow working directory → staging area (index) → repository with git add and git commit.
  • A commit is an immutable snapshot with a pointer to its parent(s). History is a graph of commits.
  • A branch is just a movable label on a commit. HEAD is a pointer to the branch (or commit) you're on.
  • Committing moves the current branch label forward — and HEAD follows because it points at the branch.
  • reset moves a label (and optionally the index/files); revert adds a new undoing commit; fetch only moves origin/* labels.

The three areas

Git keeps your work in three places. Knowing which one a command touches explains almost every Git surprise.

AreaWhat it isMoves with
Working directoryThe actual files on disk that you edit.Your editor, git switch, git restore, git reset --hard
Staging area (index)A draft of your next commit: exactly what git commit will record.git add (files in), git reset (files out)
RepositoryThe permanent database of commits (the .git folder).git commit, git fetch, git push
edit app.js          # working directory changed (not staged)
git add app.js       # copy it into the staging area
git commit -m "Add"  # snapshot the staging area as a new commit

Commits form a graph

Each commit stores a full snapshot of your files, a message, and a pointer to its parent commit. The commit's ID is a hash of all that content, so a commit can never be changed — only replaced by a new one. In the lab, arrows run from each commit to its parent: history reads right to left.

A normal commit has one parent. A merge commit has two. The first commit of a repository has none.

Branches, tags and HEAD are just pointers

A ref is a named pointer to a commit, stored as a tiny file containing a commit ID.

RefBehaviorExample
BranchMoves forward automatically when you commit on it.main, feature
TagNever moves — marks a fixed point such as a release.v1.0
Remote-tracking branchYour local bookmark of where the remote's branch was at the last fetch. Only fetch/push/pull move it.origin/main
HEADPoints at the branch you have checked out (or directly at a commit when detached). New commits get HEAD's current commit as their parent.HEAD -> main

Branching and merging

  • git branch topic creates a label at the current commit. It doesn't switch.
  • git switch topic (or checkout) moves HEAD to that branch and rewrites your working files.
  • git merge topic brings its commits into your branch: a fast-forward if your branch has nothing new (just slide the label), otherwise a merge commit with two parents.
  • git rebase main replays your branch's commits on top of main, creating new commits with new IDs.

For a deeper comparison of merge, rebase and squash, try the Git Merge vs Rebase lab.

Undoing things: reset, revert, restore

CommandMoves the branch?Changes the index?Changes your files?
git reset --soft HEAD~1YesNoNo — undone changes stay staged
git reset --mixed HEAD~1 (default)YesYes (reset to the target commit)No — changes stay but unstaged
git reset --hard HEAD~1YesYesYes — uncommitted work is lost
git revert <commit>No (adds a commit)—A new commit undoes the changes

Commits you reset away aren't deleted immediately: git reflog lists where HEAD has been, so you can recover them for a few weeks.

Remotes: push, fetch and pull

  • git push uploads commits the remote lacks and moves the remote's branch label (and your origin/* bookmark). It's rejected if it isn't a fast-forward.
  • git fetch downloads new commits and moves only your origin/* labels. It never touches your branches or files, so it's always safe.
  • git pull = git fetch + git merge origin/<branch> (or a rebase with --rebase).
git fetch                # see what teammates did: origin/main moves
git log main..origin/main  # inspect it before integrating
git merge origin/main    # now integrate

Frequently asked questions

What is HEAD in Git?
HEAD is a pointer to your current position: usually to a branch (which in turn points to a commit). When you commit, the branch HEAD points at moves forward to the new commit.
Is a Git branch a copy of the code?
No. A branch is just a small pointer (a label) to one commit. Creating a branch is instant and costs almost nothing; commits aren't copied.
What is the difference between git reset --soft, --mixed and --hard?
All three move the branch to another commit. --soft leaves the staging area and files alone, --mixed also resets the staging area but keeps your files, and --hard resets the staging area and overwrites your working files.
What is the difference between git reset and git revert?
reset moves a branch pointer, effectively rewriting history. revert creates a new commit that undoes an earlier one and leaves history intact, which is safe for shared branches.
What is the difference between git fetch and git pull?
git fetch only downloads new commits and updates your origin/* references. git pull fetches and then merges (or rebases) them into your current branch.
How do I recover a commit after reset --hard?
Run git reflog to find the commit ID where HEAD used to be, then git reset --hard <id> or git switch -c rescue <id>. Uncommitted changes that were never committed cannot be recovered.

Keep exploring

More interactive labs

All labs

Git Merge vs Rebase

Watch the commit graph change under merge, rebase and squash.

Git10 min · Beginner

HTTP Caching Explained

Cache-Control, ETag and 304s, one request at a time.

Networking12 min · Intermediate

JS Event Loop Visualizer

See the call stack, microtasks and timers run, frame by frame.

JavaScript10 min · Intermediate

CORS & Preflight Simulator

Edit the request and the server headers, then see exactly why the browser blocks it.

Networking12 min · Intermediate

What Happens When You Type a URL

DNS, TCP, TLS and HTTP — with a stopwatch.

Networking10 min · Beginner

How Database Indexes Work (B-Tree)

See a B-tree lookup beat a full table scan, and why some queries ignore your index.

Databases12 min · Intermediate

What Happens When 100 Reads Hit the Database

Connection pools, CPU workers, caches and replicas, as 100 requests arrive at once.

Databases12 min · Intermediate

SQL Isolation Levels Lab

Run two transactions side by side and watch dirty reads, phantoms and write skew appear.

Databases15 min · Advanced

Sharding & Replication

Split data across servers, copy it for reads, and see what each choice costs.

Databases15 min · Advanced

Redis Commands & Data Structures

Strings, lists, hashes, sets and sorted sets, one command at a time.

Redis15 min · Beginner

Redis Caching: Cache-Aside, TTL & Eviction

Hit or miss? Watch LRU, LFU, TTLs and a cache stampede decide your database load.

Redis12 min · Intermediate

Webhooks: Delivery, Retries & Signatures

Why you get duplicate deliveries, lost events and forged requests — and how to stop them.

Queues & Jobs12 min · Intermediate

Cron Jobs: Schedules, Overlaps & Missed Runs

Write a cron expression and watch what really happens when jobs overlap or the scheduler is down.

Queues & Jobs10 min · Beginner

Job Queues with BullMQ (Redis)

Watch jobs move through waiting, active, delayed, completed and failed — and see what BullMQ stores in Redis.

Queues & Jobs14 min · Intermediate

RabbitMQ: Exchanges, Queues, Acks & Dead Letters

Direct, topic and fanout routing, competing consumers, prefetch, redelivery and dead-letter queues, drawn.

Queues & Jobs14 min · Intermediate