Git Mental Model: Snapshots, HEAD, and References
What This Concept Is
Git is a snapshot-based content tracker. A commit is not "just the latest diff." It is a recorded project state with metadata and parent links. A branch is a movable reference to a commit. HEAD tells Git what you currently have checked out.
The core objects to keep straight are:
- working tree: the files you are editing
- index: the proposed next commit
- repository: the stored history inside
.git - branch: a name pointing to a commit
HEAD: the current checkout target, usually your current branch
Why It Matters Here
Most Git confusion comes from acting on commands before understanding what they change. If you know whether a command touches the working tree, index, branch reference, or remote, Git stops feeling magical and starts feeling predictable.
This mental model is the foundation for everything else in the module: staging, branches, merges, rebases, resets, and recovery.
Concrete Example
Start with a tiny repository:
mkdir git-model-demo
cd git-model-demo
git init
echo "v1" > notes.txt
git add notes.txt
git commit -m "Create notes"
git branch feature
At this point:
- the repository has one commit
main(ormaster, depending on your default) points to that commitfeaturepoints to the same commitHEADstill points to your current branch, not to both branches
If you now switch and commit:
git switch feature
echo "v2" >> notes.txt
git add notes.txt
git commit -m "Extend notes on feature"
git log --oneline --decorate --graph --all
you will see that only feature moved forward. The original branch did not copy files and fall behind accidentally. It simply kept pointing at the older commit.
Common Confusion / Misconception
Misconception: Branches are copies of the repository.
Correction: Branches are lightweight references. They are cheap because Git is mostly moving pointers, not duplicating full working directories.
Misconception: Git stores only differences.
Correction: Git can show diffs, but it fundamentally thinks in snapshots connected by parent relationships.
How To Use It
Before running a Git command, ask two questions:
- Which layer will this command touch: working tree, index, reference, or remote?
- Which name will move afterward:
HEAD, the current branch, a remote-tracking branch, or none?
Operational rule:
- if you do not know what object will change, inspect first with
git status,git log --oneline --decorate --graph --all, orgit branch -vv
Check Yourself
- When you create a branch, what actually changes?
- If two branch names point to the same commit, are there two copies of the files?
- What does
HEADusually point to in normal day-to-day work?
Mini Drill or Application
Create a repository with one file and do this sequence:
- Make an initial commit.
- Create a new branch called
experiment. - Switch to
experimentand make one new commit. - Run
git log --oneline --decorate --graph --all. - Explain in writing:
- which branch moved
- where
HEADpoints now - why no repository copy was created