Git Will Finally Make Sense After This
Most developers memorize Git commands without understanding the underlying model. This video builds Git from first principles — commits, graphs, pointers — so that commands like reset, rebase, and revert become logical consequences of how the system actually works rather than incantations to copy from Stack Overflow. ---
Key Concepts
| Concept | Definition |
|---|---|
| Commit | A complete snapshot of the entire project at one moment, not a diff; contains a snapshot pointer, metadata, and a pointer to its parent commit |
| DAG (Directed Acyclic Graph) | The structure formed by commits pointing to parents — directed (one-way), acyclic (no loops), graph (nodes + connections) |
| Branch | A lightweight pointer (sticky note) to a single commit hash — not a copy of the codebase |
| HEAD | Git's pointer to your current location; normally points to a branch, which in turn points to a commit |
| Detached HEAD | State where HEAD points directly to a commit instead of a branch; new commits made here are orphaned when you leave |
| Three areas | Working directory (files on disk) → Staging area/index (prepared changes) → Repository (permanent commit history) |
| Orphaned commit | A commit no branch points to; eventually removed by garbage collection |
| Reflog | A local log of everywhere HEAD has pointed recently — the recovery tool of last resort |
Notes
The Commit: Git's Fundamental Unit
- A commit stores three things:
- Commits point **backwards only** — children know parents, parents never know future children
- The first commit has no parent; merge commits have two parents
- Because each commit is a full snapshot, you can jump to any point in history instantly — no reconstruction needed
The Graph Structure
- Multiple developers branching and merging creates a **DAG**
- History is fully captured in this graph — every branch, merge, and decision
Branches Are Just Pointers
- A branch is a tiny text file containing one commit hash — nothing more
- Creating a branch is instant because nothing is copied
- When you commit on a branch, Git creates the commit and moves the branch pointer forward
- `main` is not special — just a branch pointer that convention treats as primary
HEAD: Your Current Location
- HEAD normally points to a branch (e.g., HEAD → main → commit)
- `git checkout <branch>` moves HEAD to that branch
- `git checkout <commit-hash>` puts you in **detached HEAD state**
- You can still commit, but no branch follows along
- Switching away orphans those commits — they will be garbage collected
- Warning: developers have lost hours of work this way by fixing bugs in detached HEAD without creating a branch
The Three Areas
- **Working directory**: what you see in your editor
- **Staging area (index)**: changes you've `git add`-ed, ready for the next commit
- **Repository**: permanent commit history
- `git add` moves changes from working directory → staging
- `git commit` moves staging → repository
Undoing Things: Checkout, Reset, Revert
- Non-destructive; no commits change, no branches move
- Safe for exploring history
- Orphans commits that were ahead of the new target
- Three modes, each affecting the three areas differently:
- ⚠️ Uncommitted work destroyed by `--hard` is **not recoverable**; orphaned commits may be recoverable via reflog for a limited time
- Records the inverse of a target commit as a new commit
- Original history is preserved
- Safe for undoing work that has already been pushed and shared with others
Rebase: Replaying Commits with New Parents
- **Why it's needed**: your feature branch diverged from main while main moved forward
- **What it actually does** (not "moving" commits — that's impossible):
- ⚠️ **Never rebase commits others have already seen** — their Git sees the new hashes as unrelated work, causing duplicate changes and merge conflicts
- On local, unshared branches: rebase keeps history linear and clean
- Trade-off: **clean story vs. messy truth**
Recovery: The Reflog
- `git reflog` shows everywhere HEAD has pointed recently — every checkout, commit, and reset
- Orphaned commits (from hard reset, bad rebase, etc.) are usually still findable here
- Recovery process: find the hash in reflog → `git checkout -b <new-branch> <hash>`
- Expiry: ~90 days for reachable commits, ~30 days for unreachable — act quickly
Actionable Takeaways
- Before any destructive operation (`reset --hard`, `rebase`), note your current commit hash or create a backup branch
- Never leave work in detached HEAD state — immediately run `git checkout -b <name>` if you commit anything there
- Use `git revert` instead of `git reset` when undoing commits that have already been pushed
- Never rebase commits that teammates have already pulled
- When disaster strikes, run `git reflog` before panicking — the lost commits are probably still there
- Use `git reset --soft` to squash multiple local commits before pushing
Quotes Worth Keeping
A branch is just a sticky note, a pointer, a tiny text file that contains one piece of information, the hash of a commit. That's it.
You're choosing a clean story over the messy truth.
Git almost never truly deletes anything immediately. It just hides things. The ref log is your map.