Git Will Finally Make Sense After This

LearnThatStack · 2026-05-21 ·▶ Watch on YouTube ·via captions

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

ConceptDefinition
CommitA 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)
BranchA lightweight pointer (sticky note) to a single commit hash — not a copy of the codebase
HEADGit's pointer to your current location; normally points to a branch, which in turn points to a commit
Detached HEADState where HEAD points directly to a commit instead of a branch; new commits made here are orphaned when you leave
Three areasWorking directory (files on disk) → Staging area/index (prepared changes) → Repository (permanent commit history)
Orphaned commitA commit no branch points to; eventually removed by garbage collection
ReflogA 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

  1. Before any destructive operation (`reset --hard`, `rebase`), note your current commit hash or create a backup branch
  2. Never leave work in detached HEAD state — immediately run `git checkout -b <name>` if you commit anything there
  3. Use `git revert` instead of `git reset` when undoing commits that have already been pushed
  4. Never rebase commits that teammates have already pulled
  5. When disaster strikes, run `git reflog` before panicking — the lost commits are probably still there
  6. 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.