Most git tutorials hand you a list of commands and tell you to memorize them. git add, git commit, git push — three commands you'll type a thousand times. But the moment something goes wrong — a merge conflict, a detached HEAD, a "why is my branch missing" — those tutorials leave you stranded.
This post is different. Instead of giving you another command cheat-sheet, it walks through the five concepts that make every git command obvious. Once these click, you'll never need to look up basic commands again — and the scary commands (rebase, reset, cherry-pick) stop being scary.
What you'll learn
Quick Answer
Git is built on five ideas: there are three areas for your changes (working, staging, repository), commits are full snapshots (not diffs), branches are just pointers to commits, merge and rebase are different ways to combine branches, and remote and local are independent copies. Every git command moves things between these. Once you see the picture, the commands name themselves.
Concept 1: The Three Areas
Every git command operates on one or more of three places where your code can live:
Working directory is where you edit files. Staging area (also called the index) is a "ready to commit" buffer — you put changes here when they're polished. Repository is the permanent record — once something's committed, it's saved forever.
Every git command makes more sense once you know which area it touches:
git add file.txt | working → staging |
git commit -m "..." | staging → repository |
git restore file.txt | discard changes in working |
git restore --staged file.txt | unstage (staging → working) |
git status | show what's in each area |
git diff | working vs staging |
git diff --staged | staging vs last commit |
This is why git status shows two sections — "Changes to be committed" (staging) and "Changes not staged for commit" (working). They're literally different buckets.
Concept 2: Commits Are Snapshots, Not Diffs
Most beginners think a commit stores "the changes I made". Wrong. A commit stores the entire state of your project at that moment. It's a photograph of every file, not a list of edits.
Git is smart about storage — files that don't change are stored once and referenced from multiple commits. But conceptually, every commit holds the full project. That's why you can git checkout any commit from years ago and instantly see exactly what the code looked like then.
This explains a few things:
git logshows commits in order — each is a complete snapshot, with a parent pointer to the previous one.- Reverting a commit doesn't "undo" changes — it creates a new commit whose snapshot matches what you had before.
- "Diffs" are calculated on demand by comparing two snapshots, not stored as the commit itself.
Concept 3: Branches Are Just Pointers
People imagine branches as parallel lines or copies of all the files. They're not. A branch is a 41-byte text file that holds the ID of one commit — that's it.
Creating a branch is instant — git just writes a new file containing the current commit's ID. Switching branches doesn't copy anything; git updates the working directory to match the snapshot of the target branch's commit.
HEAD is also a pointer — usually pointing at a branch (which points at a commit). When you commit, the branch you're on advances to the new commit, and HEAD follows along.
This is why:
- Branches are essentially free. Create as many as you want.
- "Deleting a branch" just removes the pointer file. The commits stay reachable from other branches.
- "Detached HEAD" means HEAD points directly at a commit instead of a branch — fine for inspection, but new commits won't be tracked by any branch and can be lost.
Concept 4: Merge vs Rebase, Visually
Both combine work from one branch into another. They produce different histories.
Before either: you have main and feature, diverged.
git merge feature (while on main) — creates a new merge commit M that has two parents:
The history shows the branch shape clearly. M's commit message is "Merge branch feature".
git rebase main (while on feature) — replays D and E on top of C, creating new commits D' and E':
Linear history. No merge commit. But — the commit IDs of D and E changed (they became D' and E'). If you'd already pushed those commits, others now have orphaned versions.
The rule:
- Use merge for shared branches that others have pulled.
- Use rebase on local-only commits to clean up history before pushing.
- Never rebase commits that exist on someone else's machine.
Concept 5: Local vs Remote (origin/main is not main)
When you clone a repo, git creates two parallel sets of branches: yours (local) and tracking copies of the server's (remote-tracking).
origin/main is git's idea of what the server's main looks like, last time you talked to the server. It's a snapshot, not a live connection. Run git fetch to refresh it.
This explains:
git statussays "Your branch is up to date with 'origin/main'" — it's comparing your local main to the cached origin/main, not the actual server.- "Your branch is 2 commits ahead" means your local has 2 commits that origin/main doesn't have yet — push to upload them.
- If you delete a remote branch on GitHub, your local
origin/that-branchstays until you rungit fetch --prune.
The 7 Commands You'll Actually Use 95% of the Time
Forget the 100-command lists. These seven cover almost everything:
git status | What's in each area, what branch you're on |
git add <files> | Stage changes ready to commit |
git commit -m "msg" | Save staged changes as a snapshot |
git push | Upload your commits to the remote |
git pull | Download + merge remote changes |
git checkout -b feature | Create and switch to a new branch |
git log --oneline --graph --all | See the history visually |
The "advanced" commands you'll need eventually:
git restore <file> | Discard a working file's changes |
git restore --staged <file> | Unstage a file (keep changes) |
git reset HEAD~1 | Undo last commit (keep changes) |
git revert <commit> | Undo a pushed commit safely |
git stash / git stash pop | Temporarily shelve changes |
git rebase main | Replay your commits on top of main |
git cherry-pick <commit> | Apply a single commit from elsewhere |
Learn Git hands-on
Our Git course walks through every concept above with interactive practice — branching, merging, conflicts, and recovery.
Start Git CourseFrequently Asked Questions
What is the difference between git add and git commit?
git add moves changes from your working directory to the staging area — it marks them ready to be committed. git commit takes everything currently in the staging area and saves it as a permanent snapshot in the repository. Two-step design lets you choose exactly what goes in each commit.
What is the difference between merge and rebase in git?
Merge combines two branches by creating a new merge commit that joins them — preserves the full history with the branch shape visible. Rebase replays your branch's commits on top of another branch — produces a linear history but rewrites commit IDs. Use merge for shared branches, rebase for cleaning up your local work before pushing.
Are git branches actual copies of files?
No. A branch in git is just a pointer (a 41-byte text file) holding the commit ID it points to. Creating a new branch is instant because nothing is copied. Switching branches just moves the HEAD pointer and updates your working directory to match that commit's snapshot.
How do I undo my last git commit?
git reset --soft HEAD~1 undoes the commit but keeps your changes staged. git reset HEAD~1 (default --mixed) keeps the changes in the working directory but unstaged. git reset --hard HEAD~1 throws away the changes entirely. If the commit was already pushed, use git revert instead — it creates a new commit that reverses the changes.
What does HEAD mean in git?
HEAD is a pointer to the commit you're currently looking at — usually the tip of the branch you have checked out. When you make a new commit, HEAD moves to that new commit. When you switch branches, HEAD moves to point at that branch. "Detached HEAD" means HEAD points directly to a commit instead of a branch — fine for inspecting, dangerous for committing.
Related Reading
The Bottom Line
Git stops being scary the moment you stop seeing it as a list of commands and start seeing the picture: three areas, snapshots, pointers, two ways to combine, and a local-remote split. Every command you'll ever run moves something between these.
The next time something feels weird — a merge conflict, a missing file, a "detached HEAD" warning — pause and ask: which area is this about? Where are the pointers? What snapshot is HEAD on? With those questions, the answer almost always reveals itself.
Skip the cheat-sheet. Internalize the model. The commands will follow.
