Safely Pause Work with git stash and Bring It Back
You will finish with a named stash that temporarily clears a dirty working tree, a way to inspect it, and a safe method for restoring the work later. The examples use Git 2.43.0 from the installed git-man package, version 1:2.43.0-1ubuntu7.3. Git's current upstream manual records no changes to this command between 2.43.0 and 2.50.1, but newer Git releases may add options.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about ten minutes. You need an existing Git repository with local changes that are not ready to commit. These commands are ordinary user commands. Nothing here needs sudo; elevated privileges can make ownership problems worse inside a working tree.
1. Check what would be stashed
Start in the repository and inspect the working tree. This does not change files or Git history:
$ cd /path/to/project
$ git --version
git version 2.43.0
$ git status --short
M src/example.c
?? notes.txt
The first column describes the index and the second describes the working tree. In this example, src/example.c is modified and notes.txt is untracked. Replace the path with your real repository, and treat the status output as the checkpoint before any state-changing command.
By default, git stash push saves tracked modifications in the index and working tree. It does not include untracked or ignored files unless you request them.
2. Create a named stash
Give the entry a short description so that it remains recognisable if several interruptions follow:
$ git stash push --message "pause parser experiment"
Saved working directory and index state On main: pause parser experiment
Running git stash without a subcommand is the same as git stash push, but the explicit form makes scripts and shell history easier to read. Git records the working directory and index, then rolls those tracked changes back to HEAD. It does not create a commit on your current branch.
Checkpoint: verify that the tracked part is clean and that the stash exists:
$ git status --short
$ git stash list
stash@{0}: On main: pause parser experiment
An empty tracked portion of the status does not mean that every file disappeared. The untracked notes.txt remains because the first command did not ask for untracked files.
3. Include untracked files only when you mean to
If the untracked files belong with the work in progress, make another stash with --include-untracked, or use that option in the original command next time:
$ git stash push --include-untracked --message "pause parser experiment with notes"
Saved working directory and index state On main: pause parser experiment with notes
$ git status --short
$ git stash list
stash@{0}: On main: pause parser experiment with notes
stash@{1}: On main: pause parser experiment
This option also cleans the included untracked files from the working tree. It does not include ignored files. The broader --all option includes ignored files too and then cleans them with git clean.
Destructive boundary: do not use --all as a convenience shortcut. Ignored build output, local configuration and other files may be removed from the working tree. Keep a separate copy of anything that is not reproducible before using it.
4. Inspect a stash before restoring it
Stashes are numbered from the newest entry, so stash@{0} is the latest and stash@{1} is the one before it. Inspect the summary first:
$ git stash show stash@{0}
src/example.c | 4 +++-
notes.txt | 1 +
2 files changed, 4 insertions(+), 1 deletion(-)
Use --patch when you need to read the actual diff. Add --include-untracked to the show command if the entry contains untracked files and you want them included in the diff:
$ git stash show --patch --include-untracked stash@{0}
The exact paths and line counts depend on your work. If no stash name is supplied, Git uses the newest one.
5. Restore without deleting the safety copy
Use apply when you want to test the restoration while keeping the stash available:
$ git stash apply stash@{0}
On branch main
Changes not staged for commit:
modified: src/example.c
Untracked files:
notes.txt
Check the result before doing more work:
$ git status --short
M src/example.c
?? notes.txt
$ git diff --check
git diff --check reports whitespace errors in the resulting worktree and is a useful, read-only sanity check. If the restored files are wrong, discard only changes you have reviewed and can recreate. The safest undo for an unwanted apply is usually to restore the affected paths from your branch or remove the newly created untracked files after checking them. Do not run a blanket cleanup command when you are unsure what is present.
If the original changes included staged work, try git stash apply --index stash@{0}. Git will attempt to restore both the working tree and the index, but this can fail when conflicts occupy the index. Without --index, the file content is restored but the original staging state is not.
6. Remove the stash only after checking the result
Once the applied files are correct, you can remove the saved entry explicitly:
$ git stash drop stash@{0}
Dropped stash@{0} (a1b2c3d4e5f6...)
The identifier in the message varies. drop removes one entry. pop combines apply and drop, but it is less forgiving: if applying the changes conflicts, Git leaves the stash in the list so you can resolve the conflict and drop it yourself. For important work, prefer apply, verify, then drop.
Irreversible boundary: git stash clear removes every stash entry. Entries then become subject to pruning and may be impossible to recover. Never use it for routine housekeeping.
7. Handle conflicts or an accidental drop
A stash can be applied on top of a different commit. If the branch has changed enough, Git may report conflicts. The stash remains available after a failed pop. Resolve the conflict markers, stage the resolved files, and run your tests before dropping the stash:
$ git status
$ git add path/to/resolved-file
$ git diff --cached --check
$ git stash drop stash@{0}
If applying to the current branch is too difficult, git stash branch restore-parser stash@{0} creates and checks out a branch from the commit where the stash was made, then applies the changes there. If that succeeds for a normal stash@{n} reference, Git drops the stash entry.
After an accidental drop or clear, stop creating unrelated repository history and try the recovery recipe documented by Git:
$ git fsck --unreachable |
grep commit |
cut -d\ -f3 |
xargs git log --merges --no-walk --grep=WIP
Recovery is not guaranteed, especially after pruning. A stash is a temporary Git object, not a replacement for a commit or backup.
Done means
- You checked
git status --shortbefore stashing. - Your stash has a useful message and appears in
git stash list. - You know whether untracked and ignored files were included.
- You inspected the diff before restoring it.
- You used
applyand verification before dropping important work. - You know that
popcan conflict, whileclearcan make entries unrecoverable.