Skip to main content

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 (or master, depending on your default) points to that commit
  • feature points to the same commit
  • HEAD still 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:

  1. Which layer will this command touch: working tree, index, reference, or remote?
  2. 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, or git branch -vv

Check Yourself

  1. When you create a branch, what actually changes?
  2. If two branch names point to the same commit, are there two copies of the files?
  3. What does HEAD usually point to in normal day-to-day work?

Mini Drill or Application

Create a repository with one file and do this sequence:

  1. Make an initial commit.
  2. Create a new branch called experiment.
  3. Switch to experiment and make one new commit.
  4. Run git log --oneline --decorate --graph --all.
  5. Explain in writing:
    • which branch moved
    • where HEAD points now
    • why no repository copy was created

Read This Only If Stuck