SovranCode
HomeCourses Git & GitHub Git Working Tree
This device
Course contentsGit Working Tree · 41 topics

1. Git Fundamentals

Git IntroductionGit Version ControlGit vs GitHubGit InstallationGit Working TreeGit RepositoryGit CommitGit .gitignoreGit Project: Learning Journal

2. Git History

Git LogGit DiffGit ResetGit RevertGit StashGit Project: Messy Repository

3. Branches & History

Git BranchGit MergeGit Merge ConflictsGit RebaseGit Cherry-PickGit TagsGit Project: Feature Branch

4. Remotes and GitHub

Git RemoteGitHub AuthenticationGitHub RepositoryGitHub ForkGitHub IssuesGitHub PagesGit Project: Two Clone Sync

5. GitHub Collaboration

GitHub Pull RequestsGitHub Code ReviewGit Branching WorkflowGitHub Branch ProtectionGitHub CollaborationGitHub ContributingGit Project: Reviewed Pull Request

6. Automation and Professional Git

GitHub ActionsGit InternalsGit RecoveryGitHub SecurityGit Project: Team Repository CIProject
Learn Git & GitHub40 complete · 1 planned

1. Git Fundamentals

Git IntroductionGit Version ControlGit vs GitHubGit InstallationGit Working TreeGit RepositoryGit CommitGit .gitignoreGit Project: Learning Journal

2. Git History

Git LogGit DiffGit ResetGit RevertGit StashGit Project: Messy Repository

3. Branches & History

Git BranchGit MergeGit Merge ConflictsGit RebaseGit Cherry-PickGit TagsGit Project: Feature Branch

4. Remotes and GitHub

Git RemoteGitHub AuthenticationGitHub RepositoryGitHub ForkGitHub IssuesGitHub PagesGit Project: Two Clone Sync

5. GitHub Collaboration

GitHub Pull RequestsGitHub Code ReviewGit Branching WorkflowGitHub Branch ProtectionGitHub CollaborationGitHub ContributingGit Project: Reviewed Pull Request

6. Automation and Professional Git

GitHub ActionsGit InternalsGit RecoveryGitHub SecurityGit Project: Team Repository CIProject
PREVIOUS LESSONGit Installation
NEXT LESSONGit Repository
1. Git Fundamentals 65 min

Git Working Tree

Trace a change through the working tree, the index, and Git objects so status and add stop feeling like magic.

What you will leave with

You will be able to trace one file through the working tree, index, and object database; explain untracked, modified, staged, and committed precisely; predict what a commit would record; and describe how blobs, trees, and commits form a snapshot.

Three places, two comparisons, one next snapshot

Working treeThe visible project files you can edit right now.
IndexThe exact tracked state currently proposed for the next commit.
ObjectsImmutable content and metadata stored inside the repository.
ComparisonsStatus words derived from differences among those states.

The three-place model

WORKING TREE              INDEX                     OBJECT DATABASE
Files you edit            Proposed next snapshot    Durable Git objects

README.md  v3    ──add──▶ README.md  v2    ─commit─▶ commit C
app.css    v1             app.css    v1              tree T
                                                     blobs B1, B2

The working tree can keep changing after the index was prepared.

The working tree and index are both mutable. Editing changes the working tree. Staging updates the index to reflect selected working-tree content. A commit then creates durable objects from the index and moves the current history reference to the new commit.

The index is not merely a waiting room

“Staging area” is friendly vocabulary, but the index is more precise: it is a structured proposed snapshot. It can contain a version of a file different from both the last commit and the current working file.

The working tree is the editable checkout

The working tree contains the directories and files checked out at your current graph position, plus untracked files Git has not selected. Your editor, formatter, compiler, and tests operate on these filesystem files. Git does not record every save automatically.

Unchanged tracked path

Working content matches the version represented in the index and current commit.

Modified tracked path

Working content differs from the index. The edit is not automatically part of the next commit.

Deleted tracked path

The working path is absent while the index or current commit still expects it.

Untracked path

The file exists in the working tree but has no index entry. Git will not commit it by accident.

Untracked does not mean ignored. An ignored path matches an exclusion rule and is normally hidden from routine status output. The later ignore lesson will cover that boundary carefully.

The index is the proposed next snapshot

For each tracked path, the index records a file mode, an object identifier, and a pathname. It does not store a vague “include this file later” flag. It identifies the exact content currently selected for the next commit.

When you stage a file, Git reads its current content, stores or reuses a blob object, and updates the index entry to that object. If you edit the file again, the index does not follow the editor. Now one path has two different new versions: the staged version in the index and the later unstaged version in the working tree.

QUICK CHECK

Test what you learned

Which Git place contains the exact version currently selected for the next commit?

Status labels come from two comparisons

PATH        HEAD        INDEX       WORKING TREE       STATUS
README.md   v1          v1          v1                 unchanged
app.css     v1          v1          v2                 modified
logo.svg    —           —           v1                 untracked
nav.js      v1          v2          v3                 staged + modified

“Modified” and “staged” are not permanent properties of a file. They describe comparisons:

  1. 01
    HEAD versus index

    If they differ, the path has a staged change proposed for the next commit.

  2. 02
    Index versus working tree

    If they differ, the path has an unstaged working change.

  3. 03
    No index entry

    If a working path is outside the tracked index and not ignored, it is untracked.

  4. 04
    Both comparisons differ

    The same path can be staged and modified at the same time.

In the matrix, nav.js is staged because index v2 differs from HEAD v1. It is also modified because working v3 differs from index v2. A commit now would record v2; v3 would remain in the working tree.

Use commands as observation windows

git status
git diff
git diff --cached
git ls-files --stage

# Read-only object inspection used later
git cat-file -t <object-id>
git cat-file -p <object-id>
Unstaged view

git diff

  • Compares working tree with index.
  • Answers what changed after staging.
  • Does not show untracked file content.
  • Does not describe the whole next commit.
Staged view

git diff --cached

  • Compares index with HEAD.
  • Answers what the proposed snapshot changes.
  • Also spelled --staged.
  • Should be reviewed before committing.

git status summarizes both comparisons and untracked paths. git ls-files --stage exposes index entries directly. The next lesson will create a repository and use these commands in a real first-commit workflow.

Commit reads the index, not the editor

A commit is built from the index. Git writes a tree representing those selected entries, then creates a commit object that points to the root tree and parent history. Unstaged working changes remain outside that commit.

  1. EDIT
    Working tree changes

    You save README v2. The index may still describe README v1.

  2. STAGE
    Index selects v2

    The proposed snapshot now contains README v2.

  3. EDIT
    Working tree advances to v3

    The proposal stays at v2 until staged again.

  4. COMMIT
    History records v2

    The commit reads the index. README v3 remains an unstaged edit.

Saving is not staging, and staging is not committing

Each verb changes a different place. Confusing them leads to commits with missing work or older staged content.

QUICK CHECK

Test what you learned

You staged version 2 and then edited version 3 without staging again. Which version would the next commit record?

The object database stores immutable values

Inside the repository metadata, Git stores objects addressed by a hash derived from object type and content. Once written, an object’s identity and content do not change. New content creates another object. This immutability makes history verifiable and allows snapshots to reuse unchanged content.

commit c7a1
  │  points to
  ▼
tree t91f  ── README.md ──▶ blob b120
           ├─ app.css  ──▶ blob a884
           └─ src/     ──▶ tree 1e03
                            └─ nav.js ──▶ blob 8dd2

The commit records the root tree, parent commit, author, dates, and message.

Blob

Stores file content. A blob does not know the project pathname, author, or original filename.

Tree

Maps names and modes to blobs and nested trees, giving a snapshot its directory structure.

Commit

Points to a root tree and parent commit, then records author, committer, dates, and message.

Tag

An annotated tag can point to another object with a name, tagger, date, message, and optional signature.

A filename belongs to a tree entry, not a blob. If two paths contain identical bytes, their tree entries can point to the same blob. If a file is renamed without changing content, Git can represent the new snapshot using the same blob under a different tree entry.

Content addressing explains reuse and integrity

An object identifier is calculated from the object’s type and content. Identical input produces the same identifier; changed input produces a different identifier. Git can therefore avoid storing duplicate immutable content and can detect when stored bytes no longer match their expected identity.

A hash is an identifier, not encryption

Object names do not hide content. Anyone with repository access can read reachable objects, and sensitive data remains sensitive even if its filename is deleted later.

Modern repositories may use SHA-1 or the newer SHA-256 object format depending on how they were created and supported tooling. The mental model is the same: object identity derives from content, and object references connect a graph.

HEAD supplies the committed comparison

HEAD identifies the current checked-out history position, usually through a branch name. Status and diff commands commonly compare the index against the commit reached by HEAD. The branch and HEAD lesson later in the course will examine those references in depth.

For now, read HEAD as “the current committed snapshot.” Then the core comparisons become:

HEAD snapshot  ⇄  index proposal  ⇄  working files
     staged changes        unstaged changes

Worked example: one file in four states

A project starts with committed README.md v1. You edit v2, stage it, then edit v3. Predict every place:

HEAD

Still points to a commit whose tree selects README v1.

Index

Selects the blob for README v2, so v2 is staged.

Working tree

Contains README v3, so a second modification is unstaged.

Next commit

Would record v2. Staging again would replace the index proposal with v3.

git diff --cached would describe v1→v2. Plain git diff would describe v2→v3. Neither comparison alone tells the entire story; together they explain the state precisely.

Independent lab: predict the three places

Do this as a paper simulation before the command workflow in the next lesson:

  1. Start with HEAD, index, and working tree all containing notes.txt v1.
  2. Edit the working file to v2. Record both comparisons.
  3. Stage v2. Record both comparisons again.
  4. Edit the working file to v3 and create untracked todo.txt.
  5. Predict what a commit would contain without staging again.
  6. Predict what remains after that commit.
Definition of done

Your answer says where v1, v2, and v3 exist; identifies todo.txt as untracked; and explains staged and unstaged as comparisons rather than labels attached forever.

Safety boundaries around repository internals

Safe inspection

Ask Git to explain itself

  • Use status and both diff views.
  • Use ls-files to inspect the index.
  • Use cat-file for read-only objects.
  • Copy a disposable repository for experiments.
Unsafe shortcut

Do not edit internals blindly

  • Do not hand-edit index bytes.
  • Do not delete unknown objects.
  • Do not treat .git as cleanup clutter.
  • Do not run destructive reset commands from memory.

The hidden .git directory is the repository database and configuration. Removing it from a working tree removes that folder’s Git history and repository identity. The visible files may remain, but their version-control graph is gone.

Common model failures

“Staged means saved.”

Saving updates a working file. Staging updates the index proposal.

“Commit takes every changed file.”

Commit reads tracked entries from the index, not every working-tree change.

“A blob is a file.”

A blob is content. Trees provide project names and structure.

“Modified and staged are exclusive.”

One path can differ across both comparisons at the same time.

Lesson review

The working tree is your editable checkout. The index is the exact proposed next snapshot. The object database stores immutable blobs, trees, commits, and tags by content-derived identifiers. HEAD provides the current committed baseline. Status and diff become predictable when you name which two places are being compared.

  • I can distinguish working-tree content from indexed content for the same path.
  • I can derive untracked, modified, staged, and staged-plus-modified states.
  • I know that a commit records the index proposal rather than every editor change.
  • I can explain how blobs, trees, and commits divide content, names, and history.
  • I can choose the correct status or diff view to inspect a suspected difference.

Related lessons

  • Git Installation — Identity is already on the commits you will create.
  • Git Repository — Initialize a repository and stage a first file.
  • Git Internals — Open the object database those three places already named.
KNOWLEDGE CHECK

Check the three-place model

Reason from comparisons instead of memorizing status colors. Each explanation names the place Git is actually reading.

01What is the working tree?
02What does the index represent most usefully?
03You stage README.md v2, then edit the working file to v3. What will a commit record for that path?
04Which comparison does git diff show by default?
05What is a blob object responsible for?
06Why can identical file content be reused across snapshots?
07A path is both staged and modified. What does that mean?
PREVIOUS LESSONGit Installation
NEXT LESSONGit Repository
ON THIS PAGEGit Working TreeThree places, two comparisons, one next snapshotThe three-place modelThe working tree is the editable checkoutThe index is the proposed next snapshotStatus labels come from two comparisonsUse commands as observation windowsCommit reads the index, not the editorThe object database stores immutable valuesContent addressing explains reuse and integrityHEAD supplies the committed comparisonWorked example: one file in four statesIndependent lab: predict the three placesSafety boundaries around repository internalsCommon model failuresLesson reviewKnowledge checkRelated lessons
Course contents