The Git Mental - Model Snapshots not Diffs
Source: Dev.to
Introduction: Why Git Feels Confusing (And How to Fix It) 💡
If you’ve ever felt lost using Git, copy‑pasting commands from Stack Overflow without understanding what they do, you’re not alone. The problem isn’t you — it’s that most Git tutorials teach commands before teaching concepts.
Imagine learning to drive by memorizing “turn the wheel 37° left, press pedal 2 inches” without understanding that the wheel controls direction and the pedal controls speed. That’s how most people learn Git!
This lesson builds the mental model that makes Git intuitive. Once you understand how Git thinks, the commands will make perfect sense. 🧠
What Git Actually Is: A Content‑Addressable Filesystem 📦
Git is not primarily a version‑control system. At its core, Git is a content‑addressable filesystem with a version‑control interface built on top.
Content‑addressable means Git stores data (files, directories, commits) and gives each piece a unique address based on its content: a SHA‑1 hash (e.g., a3f5c9b2e8d1f6a7b4c3e2d1f0a9b8c7d6e5f4a3).
🤔 Did you know? The same file content always produces the same hash, no matter where or when you save it. This makes Git efficient — if two branches have the same file, Git stores it only once.
The Key Insight: Snapshots, Not Diffs 📸
Git does not store changes (diffs). Git stores complete snapshots of your project at each commit.
| Traditional VCS | Git |
|---|---|
| Version 1: “Hello world” | Commit 1: complete snapshot of all files |
| Version 2: change line 1 | Commit 2: complete snapshot of all files |
| Version 3: add line 2 | Commit 3: complete snapshot of all files |
💡 Efficiency tip: If a file hasn’t changed between commits, Git doesn’t store it again — it creates a link to the previous version. This snapshot model is why Git is powerful for branching and merging.
The Three Areas: Where Your Code Lives 🏠
Git organizes work into three distinct areas.
1. Working Directory (Working Tree) 🌳
The actual files and folders you see and edit. Nothing affects Git’s history until you tell Git about it.
2. Staging Area (Index) 🎬
A unique feature that lets you assemble exactly what will go into the next snapshot.
- Add specific files:
git add file.txt - Add parts of files:
git add -p file.txt - Review staged changes before committing
The staging area enables clean, logical commits even when you’ve changed many files.
3. Repository (.git folder) 🏛️
The permanent database where Git stores:
- All commits (complete snapshots)
- All branches
- Full history and metadata
When you run git commit, Git takes everything from the staging area and creates a permanent snapshot in the repository.
⚠️ Important: Once committed, data is nearly impossible to lose. Even deleted commits are usually retained for weeks.
How Commits Actually Work 🔗
A commit is Git’s fundamental unit and contains:
- A complete snapshot of all staged files
- Metadata (author, email, timestamp, message)
- Parent commit(s) – pointers to previous commit(s)
- A unique SHA‑1 hash (the commit’s address)
Commit: a3f5c9b
Author: Jane Developer
Date: 2024-01-15 10:30
Message: Add login feature
Parent: f2e4d8a
Snapshot:
- index.html (hash: d3a2...)
- style.css (hash: b7f1...)
- app.js (hash: e8c4...)
Each commit points to its parent, forming a directed acyclic graph (DAG) that represents the project’s history.
🧠 Mnemonic: Think of commits as linked snapshots — each one is complete but knows where it came from.
Detailed Examples: The Three Areas in Action 🎯
Example 1: Creating Your First Commit
-
Create a file
echo "Hello Git" > readme.txtWorking Directory:
readme.txt(new)
Staging Area: empty
Repository: empty -
Stage the file
git add readme.txtWorking Directory:
readme.txt
Staging Area:readme.txt(staged)
Repository: empty -
Commit the snapshot
git commit -m "Add readme file"Working Directory:
readme.txt
Staging Area: clean (matches repository)
Repository: commita3f5c9b– “Add readme file” (containsreadme.txt)
Example 2: Multiple Changes, Selective Staging
Assume a project with index.html and styles.css already committed. You make three changes:
- Bug fix in
index.html - New feature in
index.html - Color update in
styles.css
Goal: Two separate commits – one for the bug fix, one for the feature + styling.
# Stage only the bug‑fix hunks from index.html
git add -p index.html # select the bug‑fix hunks
git commit -m "Fix navigation bug"
Now the first commit contains only the bug fix.
# Stage the remaining changes (feature + styling)
git add index.html styles.css
git commit -m "Add new feature and update colors"
The second commit captures the feature addition and the style changes, keeping the history clean and logical.