Chapter 12Lesson 01~85 minutes

Stash, Worktrees, Temporary Work, and Parallel Development Contexts: Concepts, Architecture, and Mental Model

Understand stash as commit-based local state referenced by refs/stash, compare tracked/untracked/ignored stash scope, and model linked worktrees as independent checkout/index/HEAD contexts sharing one repository.

Stash internalsWorktree modelTemporary stateParallel contexts

Learning objectives

  • Explain stash entries as commit-based working/index state referenced through refs/stash and its reflog.
  • Choose deliberately among tracked-only, untracked-inclusive, ignored-inclusive, staged-only, and path-scoped stashes.
  • Explain what linked worktrees share and which working/index/HEAD state remains separate.
  • Apply branch checkout exclusivity across worktrees as a safety invariant.
  • Distinguish short-lived local context state from durable collaborative history.

1. The context-switching problem

Release work, code review, an urgent production fix, and unfinished feature development often overlap. Chapters 04–11 taught you how Git records working-tree state, index state, branch refs, history, collaboration, recovery, and releases. The new problem is not “how do I save a file?” It is how do I preserve one work context while entering another without hiding work, overwriting state, or creating unnecessary clones?

Git offers two different tools for two different shapes of interruption. A stash temporarily records local state and usually cleans the current worktree. A linked worktree gives the same repository another working directory with its own checkout state, allowing parallel branches or detached review snapshots without switching the first directory away.

2. Inspect current contexts before creating another one

git rev-parse --show-toplevel
git status --short --branch
git branch -vv
git stash list
git worktree list --porcelain
git rev-parse --git-dir
git rev-parse --git-common-dir

These commands answer six questions: Which repository am I in? Is this worktree dirty? Which branch is active? Is local work already hidden in the stash stack? Which worktrees already exist? Which administrative directory is specific to this worktree versus shared by the repository?

3. A stash is commit-based state referenced through refs/stash

The newest normal stash entry is named by refs/stash. Older entries are recorded in that ref's reflog and appear as stash@{0}, stash@{1}, and so on. This is why git stash list feels like a stack even though the recorded state is made from Git commit objects.

git stash list
git rev-parse --verify refs/stash
git reflog show refs/stash
git show --no-patch --format='%H %P %s' stash@{0}

If no stash exists, refs/stash is absent. Do not treat stash numbering as a permanent identifier: dropping an entry changes later indexes. Capture the stash OID or a meaningful message when exact evidence matters.

4. A stash records separate working-tree and index views

For ordinary tracked changes, Git documents a stash entry as a commit whose tree records the working-directory state. Its first parent is the commit that was HEAD when the stash was created; another commit records the index state. Conceptually:

Tracked-state stash structure
flowchart LR
H[H: original HEAD commit]
I[I: saved index state]
W[W: stash commit / saved worktree state]
H --> I
H --> W
I --> W
RS[refs/stash] --> W

H anchors the context where the work began. I preserves what was staged. W preserves the broader tracked working-tree snapshot. refs/stash points at the newest stash entry. When untracked or ignored content is explicitly included, Git records additional internal state; scripts should use porcelain commands rather than assuming a fixed private parent layout.

5. Default stash scope is not “everything in the directory”

Command choice Tracked changes Untracked Ignored
git stash push Yes No No
git stash push -u Yes Yes No
git stash push -a Yes Yes Yes
git stash push --staged Only staged changes Only if represented by staged content No
git stash push -- path Only matching selected paths Depends on other options Depends on other options

This distinction is operationally important. A default stash can make tracked files clean while leaving an untracked migration draft or generated diagnostic file behind. Always inspect git status after stashing.

6. Apply, pop, drop, and branch are different recovery choices

  • git stash apply stash@{n} applies the recorded state but keeps the stash entry.
  • git stash pop stash@{n} tries to apply it and, only on success, removes that stash entry.
  • git stash drop stash@{n} removes one stash entry from the normal stash list without applying it.
  • git stash branch rescue/name stash@{n} creates a branch at the commit where the stash began, applies the stash there, and drops that stash if the apply succeeds.

stash branch is especially useful when the original branch has moved enough that applying the stash to today's tip would conflict.

7. Linked worktrees share repository storage but have independent checkout state

A repository can have one main worktree and zero or more linked worktrees. They share the common object database and most repository refs/configuration, but each worktree has its own working directory, index, HEAD, and other per-worktree administrative state.

One repository, three working contexts
flowchart TB
COMMON[Common repository: objects + shared refs/config]
COMMON --> MAIN[Main worktree: HEAD=trunk + own index + files]
COMMON --> FEAT[Linked worktree: HEAD=feature/metrics + own index + files]
COMMON --> HOT[Linked worktree: HEAD=hotfix/timeout + own index + files]
MAIN -. same commit objects can be read .-> COMMON
FEAT -. commits write into shared object DB .-> COMMON
HOT -. commits write into shared object DB .-> COMMON

The arrows from the common repository mean each directory sees the same commit/object universe. The separate worktree boxes mean an edit or staged file in one worktree does not become an unstaged/staged file in another. A commit created in one worktree, however, immediately exists in the shared repository and can be inspected from the others.

8. One ordinary branch is normally checked out in only one worktree

Git normally refuses to add or switch another worktree to a branch that is already checked out somewhere else. This prevents two directories from independently updating the same branch ref while each index/working tree assumes it owns that branch.

git worktree list
git branch -vv

If a branch has a worktree path beside it, go to that context or remove/reassign that worktree deliberately. Do not bypass the safeguard merely because the refusal is inconvenient.

9. Temporary state is not durable collaborative history

Need Better representation Why
Minutes-hours interruption; private incomplete changes Named stash Fast local context parking
Parallel hotfix/review while current tree must remain untouched Linked worktree Separate checkout state, shared object database
Work must survive handoff/review/CI/reboot uncertainty Commit on a branch Durable, addressable, shareable history
Independent security boundary or reproducible fresh environment Fresh clone/workspace Stronger isolation than a shared worktree repository

A stash is local hidden state, not a team task tracker. A worktree is another directory, not a backup. Neither replaces meaningful commits when the work is important enough to preserve or share.

10. DevOps connection — explicit contexts reduce operational mistakes

During an incident, the dangerous failure is often not Git corruption; it is running a deployment, formatter, migration, or build from the wrong source context. Worktrees can keep review, feature, release, and hotfix directories distinct. Stash can park a short-lived local interruption. Both should be paired with preflight checks such as current path, branch, exact OID, status, and intended environment.

11. Knowledge check

Question 1. Where is the newest normal stash entry referenced?

Question 2. Does a default git stash push include an untracked file?

Question 3. What state is separate between linked worktrees?

Question 4. Why does Git normally refuse the same branch in two worktrees?

Question 5. When is a commit safer than a stash?

12. Summary

Stash is commit-based local state referenced by a special reflog-backed ref; worktrees are parallel checkout contexts attached to one repository. Scope matters: tracked, untracked, ignored, staged, and selected-path stash choices are different. Durability matters too: stash/worktree are context-management tools, while branches and commits remain the durable collaboration model.

Next

Operate the stash stack and multiple worktrees safely

Lesson 2 builds selected/staged stashes, demonstrates apply/pop/drop/branch including a conflict, then creates feature, review, and hotfix worktrees and cleans their metadata deliberately.

Authoritative references

 git-stash
 git-worktree
 gitrepository-layout

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.