Chapter 04Lesson 01~65 minutes

Repositories, Working Tree, Index, HEAD, and the File Lifecycle: Concepts, Architecture, and Mental Model

Make Git's everyday state model explicit: working tree, index, HEAD, current branch, object database, file states, detached HEAD, pathspecs, and revision/path separation.

Working treeIndexHEADPathspecs

Learning objectives

  • Explain the working tree, index, HEAD, current branch, and object database as distinct layers.
  • Interpret untracked, ignored, modified, staged, committed, deleted, and renamed states as layer comparisons.
  • Treat the index as the exact proposed next snapshot rather than a vague holding area.
  • Distinguish symbolic HEAD from detached HEAD and explain the retention risk of unnamed commits.
  • Use status, diff, ls-files, rev-parse, and symbolic-ref as read-only state probes.

1. The problem — “my file changed” is not one Git state

Chapter 03 showed that committed history is built from immutable objects and movable refs. Everyday Git work happens in front of that object database, where the same path can have three different versions at once: the version recorded by HEAD, the version prepared in the index, and the version currently on disk in the working tree.

Most accidental data loss and many bad commits begin when a command is chosen by vague intent—“undo this,” “save this,” “remove this”—instead of by the layer that should change. This chapter replaces those verbs with a state model you can inspect before and after every operation.

2. Four layers you must keep separate

Layer Question it answers Typical inspection
Working tree What files/content are physically checked out right now? git diff, filesystem tools
Index / staging area What snapshot is proposed for the next commit? git diff --staged, git ls-files --stage
HEAD What commit is currently checked out? git rev-parse HEAD, git symbolic-ref -q HEAD
Object database Which immutable blobs/trees/commits already exist? git cat-file, git ls-tree

3. State-flow mental model

Everyday path state flows
flowchart TD
H[HEAD commit tree] -->|git restore --staged path| I[Index: proposed next snapshot]
H -->|commit supplies baseline| I
I -->|git restore path| W[Working tree]
W -->|git add path| I
I -->|git commit| C[New commit]
C -->|current branch moves| H2[New HEAD commit]
W -. untracked path .-> U[Not in index]
G[Ignore rules] -. suppress ordinary untracked reporting .-> U

The arrows are deliberately directional. git add copies selected working-tree content into the index; it does not “send a file to GitHub.” A normal git commit records the index as a new commit and advances the current branch. git restore can copy content toward the working tree or, with --staged, reset index content from a source such as HEAD.

4. The index is a proposed next snapshot, not a waiting room

Calling the index a “staging area” is convenient but incomplete. It contains path entries, modes, and object IDs representing the exact content Git would normally place into the next commit. That is why a file can be staged and then modified again: the index keeps the staged version while the working tree moves on.

git status --short
git diff
git diff --staged
git ls-files --stage

The first diff compares working tree to index. The staged diff compares index to HEAD. Together they explain the two columns in short status.

5. File states are comparisons, not permanent labels

  • Untracked: exists in the working tree but has no index entry and is not ignored.
  • Ignored: normally untracked and matched by an active exclude rule; tracked files do not become untracked merely because a pattern later matches them.
  • Modified: working-tree content differs from the index, or an index entry differs from HEAD, depending on which comparison you mean.
  • Staged: the index differs from HEAD for that path.
  • Committed: content is reachable through a commit snapshot such as HEAD.
  • Deleted: a tracked path is absent from the working tree or staged absent from the next snapshot.
  • Renamed: status/diff may report a rename when comparing snapshots and finding sufficiently similar content; Git does not create a special rename object.

7. Pathspecs select paths; revisions select history

A pathspec is Git's syntax for limiting commands to paths. It is not identical to shell globbing. The shell may expand an unquoted wildcard before Git ever sees it, while a quoted pathspec is interpreted by Git.

git status -- "docs/*.md"
git diff HEAD -- README.md
git add -- "src/*.py"

The standalone -- means “stop parsing revisions/options; what follows is path selection.” It is especially valuable when a path resembles a branch, tag, revision, or option.

8. Inspection ladder before mutation

git rev-parse --show-toplevel
git status --short --branch
git symbolic-ref -q HEAD
git rev-parse --verify HEAD
git diff
git diff --staged
git ls-files --stage
git ls-tree -r HEAD --name-only

This ladder answers, in order: which repository, which branch/HEAD state, what the working tree changed relative to the index, what the index changed relative to HEAD, what is actually in the index, and what HEAD records.

9. DevOps connection — pipelines act on exact layers too

CI scripts that generate files, stage release metadata, or inspect a checkout must know whether they are reading committed source, dirty working-tree content, or staged-but-uncommitted state. Packaging a dirty working tree when the policy requires an exact commit is a provenance error; committing unintended generated files because git add . was used casually is a release-quality error.

10. Knowledge check

Question 1. A file was staged, then edited again. Which two diffs can both show changes?

Question 2. Does adding a path to .gitignore automatically remove an already tracked copy from the index?

Question 3. What does a detached HEAD mean?

Question 4. Why use -- before a path such as release?

11. Summary

Everyday Git is a controlled movement among working tree, index, HEAD, and immutable objects. The index is the exact proposed next snapshot; status and diff are comparisons among layers; HEAD can be symbolic or detached; pathspecs control which paths a command touches.

Next

Move paths through the state machine deliberately

Lesson 2 creates a disposable repository and makes each transition observable with status, both diff directions, add/add -p, restore, rm, mv, ls-files, and ignore inspection.

Authoritative references

 git-status
 Git glossary
 git-diff
 git-ls-files

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.