|$ curl https://forge-ai.dev/api/markdown?path=docs/git/stashing
$cat docs/git-—-stashing-&-worktrees.md
updated Recently·12 min read·published

Git — Stashing & Worktrees

GitIntermediate
Introduction

Git stash and worktrees solve two fundamental workflow problems: temporarily setting aside uncommitted work, and working on multiple branches simultaneously without interference.

Stash lets you save your dirty working directory and staging area to a stack of temporary states, while worktrees allow multiple branches to be checked out in separate directories using a single Git repository.

git stash Basics

The git stash command temporarily saves your modified tracked files and staged changes so you can work on something else, then reapply them later. Think of it as a clipboard for your working directory.

terminal
Bash
1# Stash current changes (tracked files only)
2git stash
3
4# Stash with a descriptive message
5git stash push -m "WIP: payment form validation"
6
7# List all stashes
8git stash list
9# stash@{0}: On feature/payments: WIP: payment form validation
10# stash@{1}: On main: fix login redirect
11
12# Apply the most recent stash (keep it in stash list)
13git stash apply
14
15# Apply a specific stash
16git stash apply stash@{1}
17
18# Apply and remove from stash list (pop)
19git stash pop
20
21# Drop a specific stash without applying
22git stash drop stash@{1}
23
24# Clear the entire stash list
25git stash clear

info

Always add a descriptive message with git stash push -m. Without a message, stashes are identified only by their index, which becomes difficult to manage when you have multiple stashes saved.
Partial Stashing (--patch)

The --patch flag (or -p) lets you stash individual hunks of changes from a file, rather than the entire file. This is useful when a file contains both work-in-progress and changes you want to commit separately.

terminal
Bash
1# Stash only selected hunks interactively
2git stash --patch
3
4# You'll be prompted for each hunk:
5# @@ -10,7 +10,7 @@ function validate(form) {
6# - const email = form.email.value;
7# + const email = form.email.value.trim();
8# Stage this hunk [y,n,q,a,d,/,s,e,?]?
9
10# Options:
11# y - stash this hunk
12# n - don't stash this hunk
13# s - split this hunk into smaller hunks
14# q - quit (don't stash remaining hunks)
15# a - stash this hunk and all remaining hunks
16# d - don't stash this hunk or any later hunks
17# ? - print help

After partial stashing, you can commit the unstaged changes (which represent the clean, ready-to-commit portion) and later reapply the stashed work.

Stashing Untracked Files

By default, git stash only stashes tracked files — files that Git is already aware of. To include untracked files (new files not yet added), use the -u or --include-untracked flag.

terminal
Bash
1# Stash tracked + untracked files
2git stash --include-untracked
3# Short form:
4git stash -u
5
6# Stash everything including ignored files
7git stash --all
8# WARNING: This stashes node_modules/, .env, etc.
9# Use with extreme caution
10
11# Check that untracked files were stashed
12git stash list
13git stash show -p stash@{0} | head -20

warning

Be careful with git stash --all — it includes ignored files (like node_modules). This can create a huge stash and slow down your repository. Prefer git stash -u to include only untracked files without ignored ones.
Stashing to a Specific Index

The git stash command also accepts the --index flag, which tells Git to try to reapply both the staged (index) and unstaged (working tree) changes separately when applying the stash.

terminal
Bash
1# Stash including the index state
2git stash --index
3
4# When applying, Git restores:
5# - Staged changes back to the staging area
6# - Unstaged changes back to the working directory
7
8# This is useful when you have partially staged files
9git add config.js # staged
10# edit src/app.js # unstaged
11git stash --index # saves both states separately
12git stash apply --index # restores both correctly
Applying Stashes to Branches

If you stash changes and later realize they should live on a different branch, git stash branch creates a new branch based on the commit where the stash was originally created, applies the stash, and drops it from the stash list.

terminal
Bash
1# Create a new branch from the stash commit and apply
2git stash branch new-feature stash@{0}
3
4# This is equivalent to:
5# 1. git checkout <commit-where-stash-was-made>
6# 2. git checkout -b new-feature
7# 3. git stash apply stash@{0}
8# 4. git stash drop stash@{0}
9
10# If your current branch has diverged significantly:
11# The stash might not apply cleanly.
12# Using git stash branch avoids conflicts by starting
13# from the exact state where the stash was created.
14
15# Apply to current branch (if compatible):
16git stash apply stash@{0}
🔥

pro tip

Use git stash branchwhen you apply a stash and realize the changes belong on a new or different branch. It handles the branch creation and stash application in one command, avoiding the common "dirty working directory" error.
Git Worktree Fundamentals

A Git worktree allows you to check out multiple branches simultaneously in separate directories, all sharing the same Git repository (objects, refs). This eliminates the need to stash changes or clone the repo multiple times.

Worktrees share the .gitdirectory's object store and references, so disk usage is minimal — only the checked-out files in each worktree take additional space.

terminal
Bash
1# List all worktrees
2git worktree list
3# /Users/me/project main [abc1234]
4# /Users/me/project-hotfix hotfix [def5678]
5# /Users/me/project-feature feature [ghi9012]
6
7# Add a new worktree (creates directory and checks out branch)
8git worktree add ../project-hotfix hotfix
9
10# Add a worktree for a new branch
11git worktree add -b new-feature ../project-feature main
12
13# Remove a worktree
14git worktree remove ../project-hotfix
15
16# Prune stale worktree references (after manual deletion)
17git worktree prune
Creating & Managing Worktrees

Worktrees can be created from existing branches or new branches. Each worktree has its own working directory, index, and HEAD reference, allowing completely independent work.

terminal
Bash
1# Create worktree from existing branch
2git worktree add /path/to/hotfix-fix bugfix-123
3
4# Create worktree with a new branch based on main
5git worktree add -b feature/dashboard /path/to/dashboard main
6
7# Create worktree from a tag (detached HEAD)
8git worktree add /path/to/release-v2 v2.0.0
9
10# Lock a worktree to prevent pruning
11git worktree lock /path/to/hotfix-fix --reason "Active hotfix"
12
13# Unlock a worktree
14git worktree unlock /path/to/hotfix-fix
15
16# Move a worktree to a new location
17git worktree move /path/to/old /path/to/new
18
19# Get detailed info about a worktree
20git worktree list --porcelain

info

Always lock a worktree if you plan to keep it long-term. Use git worktree lock to prevent accidental pruning by git worktree prune, which removes worktrees whose linked directory no longer exists.
Use Cases for Worktrees

Reviewing Pull Requests

Create a worktree from a colleague's feature branch to review their code locally without disturbing your current work. When done, simply remove the worktree.

Hotfix While Working on Features

A production bug appears while you're deep in a feature branch. Create a worktree from main, fix the bug, commit, push, and delete the worktree — all without stashing or interrupting your feature work.

Running Parallel CI/Test Environments

Run tests on different branches simultaneously by creating worktrees for each branch. This is especially useful for monorepos where different packages need testing on different branches.

Long-Running Experiments

Keep an experimental branch checked out in a separate worktree, allowing you to work on it whenever inspiration strikes without context-switching your main working directory.

Best Practices

Keep Stashes Temporary

A stash should be short-lived — a few hours at most. If a stash sits for days, create a branch instead. Stashes are not a replacement for branches; they are a temporary scratch pad.

Name Your Stashes

Always use git stash push -m with a descriptive message. Without names, stashes are just stash@{N} entries that become cryptic once you have more than a few.

Worktrees Over Multiple Clones

Use worktrees instead of cloning the repository multiple times. Worktrees share the object store, saving disk space and ensuring you never forget to git fetch in one of the clones.

Prune Stale Worktrees

Run git worktree prune periodically or after manually deleting a worktree directory to keep the worktree list clean and avoid confusion.

$Blueprint — Engineering Documentation·Section ID: GIT-STASH·Revision: 1.0