100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Bash

The Three States of Git

Understand Git's core mental model — working directory, staging area, and repository — and how files move between them during a typical edit-commit cycle.

The Basic WorkflowBeginner7 min readJul 9, 2026
Analogies

The Three States of Git

Git organizes every tracked file into one of three conceptual states: modified, staged, and committed. A file is modified when it has been changed on disk but Git has not yet been told to include that change in the next snapshot. It becomes staged once you run git add, which records it in the staging area (also called the index) as part of the next commit. It becomes committed once git commit writes that snapshot permanently into the local repository's object database. These three states map directly onto three physical locations Git manages: the working directory, the staging area (.git/index), and the .git directory itself (the repository proper).

🏏

Cricket analogy: A player's involvement moves through three physical locations — the practice nets where changes happen, the official team-sheet folder at the ground, and the match archive that permanently records who actually played once the toss happens and the game is committed to record.

The working directory

The working directory is simply the checked-out set of files you see and edit in your file manager or editor — a single version of the project pulled out of the compressed database in .git. Files here can be untracked (Git has never seen them), unmodified (matching the last commit), or modified (different from the last commit). Running git status is the fastest way to see which category each file currently falls into.

🏏

Cricket analogy: The actual playing eleven on the field is the working directory — a single live version pulled from the club's full historical database; a player might be a brand-new trialist, performing exactly as scouted, or visibly playing differently than their file suggests, and the coach's live radio check is the fastest way to know which.

The staging area (index)

The staging area is a binary file, .git/index, that stores a snapshot of what will go into your next commit — it is not simply a list of filenames but a full tree of blob references. This intermediate step is what lets you build a commit incrementally: you can stage only part of your changes with git add -p, review exactly what is staged with git diff --cached, and unstage without losing work using git restore --staged <file>. This separation between "what changed" and "what will be committed" is one of Git's most distinctive design decisions compared to older version control systems.

🏏

Cricket analogy: The official team-sheet document isn't just a list of names — it's a full record of each player's exact confirmed role and batting position; a captain can name only part of the squad first, review exactly who's confirmed so far, and pull a player off the sheet without sending them home from the ground.

bash
$ git status
On branch main
Changes not staged for commit:
  modified:   src/api/routes.py
Untracked files:
  models/user_v2.py

$ git add src/api/routes.py
$ git status
Changes to be committed:
  modified:   src/api/routes.py
Untracked files:
  models/user_v2.py

$ git commit -m "Add pagination support to routes"
[main 4f9a1c2] Add pagination support to routes
 1 file changed, 12 insertions(+), 2 deletions(-)

$ git status
Untracked files:
  models/user_v2.py   # still untracked — not part of the commit

The .git directory (repository)

Once git commit runs, Git takes everything currently in the staging area, wraps it into a new commit object pointing at the previous commit as its parent, and stores that object permanently (until explicitly rewritten) in the .git directory's object database. At this point the change is part of the project's committed history and can be viewed with git log, diffed against other commits, pushed to a remote, or checked out later — it is far more durable than a staged or modified change, both of which live only in your local working copy and index.

🏏

Cricket analogy: Once the umpires confirm the result, everything on the team sheet gets wrapped into the official match record pointing back at the previous match, filed permanently in the league archive — from then on it can be looked up, compared, cited, or replayed, far more durable than a team sheet that never made selection.

A useful analogy: the working directory is your desk where you're actively drafting, the staging area is an envelope you're carefully filling with the pages you've decided belong in today's letter, and the repository is the mailbox — once a commit is 'posted', it has a permanent, addressable record.

  • The three states — modified, staged, committed — correspond to the working directory, the index, and the .git object database.
  • git add moves changes from modified to staged; git commit moves staged changes into a permanent commit.
  • The staging area lets you build a commit incrementally, staging only part of your working changes if desired.
  • git status reports which state every tracked and untracked file is currently in.
  • git diff compares working directory to the index; git diff --cached compares the index to the last commit.
  • Committed snapshots are durable and addressable by hash; staged and modified changes are not yet part of history.

Practice what you learned

Was this page helpful?

Topics covered

#Bash#GitVersionControlStudyNotes#SoftwareEngineering#TheThreeStatesOfGit#Three#States#Git#Directory#StudyNotes#SkillVeris