datarekha

The three trees: working, staging, repo

Understand the three zones Git uses to track your work — and why a separate staging step gives you precise control over every commit.

7 min read Beginner Git Lesson 3 of 15

What you'll learn

  • What the working directory, staging area, and repository each store
  • How git add and git commit move changes between those zones
  • Why staging lets you craft clean, focused commits instead of all-or-nothing snapshots

Before you start

The previous lesson ended on a puzzle: when you commit, Git does not snapshot your working folder directly — it snapshots a staging area in the middle, one you load by hand. That middle zone sounds like a needless extra step until you see what it buys you. So let us name all three zones precisely, watch a change travel through them, and only then ask why the one in the middle earns its place.

The core mental model

Every file in a Git project lives in exactly one of three zones at any moment. Think of them as three distinct containers — not folders you can open in Finder, but states of knowledge that Git maintains.

Working Directory — your real files, exactly as they exist on disk right now. When you open a file in your editor and type something, you are changing the working directory. Git can see these changes, but it has not recorded them anywhere yet.

Staging Area (also called the index) — a holding zone where you compose the next snapshot. Nothing is permanent here; it is a proposed commit waiting for your approval. You populate it deliberately, one file (or one hunk) at a time.

Repository (the .git directory) — the permanent, compressed history of every commit you have ever made. Once a snapshot lands here, it is safe and retrievable forever, even if you delete the file from your working directory.

Visualizing the flow

Working Directoryyour files on diskStaging Areaproposed next snapshotRepositorypermanent history (.git)git addgit commit
The three trees: changes flow left to right, one deliberate step at a time.

Walking through the flow

1. Edit a file (working directory changes)

Open README.md and add a line. From Git’s perspective the file is now modified — changed on disk relative to what was last committed — but Git has not been asked to record anything.

2. Stage the change (git add)

git add README.md

Git takes a snapshot of README.md as it is right now and places that snapshot in the staging area. The working directory still has your edits; the staging area now also knows about them.

3. Commit the snapshot (git commit)

git commit -m "Add project overview to README"

Git wraps everything in the staging area into a permanent commit object, writes it to the repository, and clears the staging area. The working directory is unchanged.

Reading the three zones with git status

git status is your live map of which zone each file is in. Learn to read it fluently.

Scenario A — a brand new file that has never been added:

git status
On branch main

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        notes.txt

nothing added to commit but untracked files present

notes.txt exists in the working directory but is invisible to the staging area and repository.

Scenario B — an existing file edited but not yet staged:

git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
        modified:   README.md

no changes added to commit

Scenario C — after git add README.md:

git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   README.md

“Changes to be committed” means the file is in the staging area, ready for git commit.

Why does the staging area exist?

This is the question most beginners never ask — and the answer is the whole point.

Imagine you spent an afternoon making two unrelated changes: you fixed a bug in auth.py and added a new feature in dashboard.py. Without a staging area you would have to commit both together, muddying your history. With the staging area you can do this:

git add auth.py
git commit -m "Fix login redirect bug"

git add dashboard.py
git commit -m "Add user dashboard page"

Two clean, focused commits from one editing session. The staging area is a curation tool — it lets you decide exactly what story your history tells, independently of the order you actually wrote the code.

A quick note on git init

When you run git init in a folder, Git creates a hidden .git directory. That directory is the repository — it holds the index (staging area) and all committed history. The files outside .git are your working directory. Everything flows from that one git init command.

In one breath

Every changed file sits in exactly one of three zones: the working directory (your real files on disk), the staging area (a snapshot you compose by hand as the proposed next commit), and the repository (the permanent .git history). git add copies a file’s current state from working directory into staging; git commit seals everything staged into permanent history and clears the stage. The staging area is the part beginners skip and experts lean on — it is a curation tool that lets you split one messy editing session into clean, focused commits, so your history tells the story you choose rather than the order you happened to type.

ZoneWhat it holdsHow you move changes in
Working DirectoryYour current files on diskEdit in your editor
Staging Area / IndexThe proposed next commitgit add
Repository (.git)Permanent committed historygit commit

git status shows which zone each changed file is in at any moment — reading it fluently is 80 percent of understanding Git.

Practice

Before the quiz, trace the snapshot rule: you edit auth.py and dashboard.py in one sitting, run git add auth.py, then make one more tweak to auth.py, then git commit -m "fix auth". Exactly which version of which file lands in that commit — and what does git status show for each of the two files the moment the commit finishes?

Quick check

0/3
Q1You edit app.js and run `git add app.js`. Then you make more edits to app.js. What does the next `git commit` include?
Q2Which git status section tells you a file is in the staging area, waiting to be committed?
Q3A teammate asks why you made two separate commits instead of one big commit for yesterday's work. Which reason best reflects the purpose of the staging area?

A question to carry forward

You can now name the three zones and read git status like a map. But so far “stage a change” has meant the simplest case — git add one-file.py. Real editing sessions are messier: you touch eight files, want six of them in this commit and two in the next, and inside a single file you may want only some of the lines. Can the staging area really be that surgical — down to individual hunks of one file — and once something is staged, how do you write a commit message your future self will actually thank you for? That is the next lesson: staging and commits, in full.

Sign in to track your progress

Completed lessons, your XP, level, and streak save to your account — it's free and takes a few seconds.

Practice this in an interview

All questions
Why isn't a git commit enough to reproduce an ML training run?

A git commit captures code, but an ML run also depends on the exact training data, hyperparameters, environment, and randomness, none of which live in Git. Datasets are too large for Git and change independently of code, so you need a data-versioning tool like DVC or lakeFS to pin a content hash of the data to the commit. Full reproducibility means versioning code, data, config, environment, and seeds together and linking them.

How does DVC differ from a feature store, and when would you reach for each?

DVC (and lakeFS) version raw datasets and model artifacts as immutable snapshots tied to Git commits, giving reproducibility and rollback. A feature store manages computed features for training and serving, its main job being to keep offline and online feature definitions in sync to prevent training-serving skew. They are complementary: DVC answers what data made this model, while a feature store answers how do I serve the same features consistently.

What's the difference between experiment tracking and a model registry, and why do you need both?

Experiment tracking logs every run, its parameters, metrics, and artifacts, so you can compare and reproduce experiments during development. A model registry is the curated, governed catalog of the few models you actually intend to deploy, with versioning, stage or alias management, approvals, and lineage. You need both because tracking gives breadth for exploration while the registry gives the controlled, auditable path to production.

How do you safely promote a model to production using a model registry?

Register every candidate as an immutable, versioned artifact, then move it through environments (dev to staging to prod) gated by automated checks rather than promoting straight to prod. In modern MLflow you use aliases like champion and challenger instead of the deprecated stage labels, and promotion is a governed, auditable action with sign-off and an easy rollback by repointing the alias. Always validate in staging and roll out progressively (canary or shadow) before full traffic.

Related lessons

Explore further

Skip to content