Git
Git Stash
File Extraction
Programming
Code Management

How would I extract a single file (or changes to a file) from a git stash?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

To extract a single file from a git stash without applying the entire stash, use git checkout (or git restore in Git 2.23+) to pull that specific file from the stash reference into your working directory.

bash
1# Git 2.23+ (recommended)
2git restore --source stash@{0} -- path/to/file.txt
3
4# Older Git versions
5git checkout stash@{0} -- path/to/file.txt

Both commands replace the file in your working directory with the version saved in the stash. The rest of the stash remains untouched, and the stash itself is not dropped.

Understanding Stash References

A git stash is internally a commit object. When you run git stash push, Git creates a commit that captures your working directory changes (and optionally staged changes and untracked files). These commits are stored in a stack:

  • stash@{0} is the most recent stash.
  • stash@{1} is the one before that.
  • stash@{N} is the Nth stash in the stack.

List all stashes with:

bash
git stash list
text
stash@{0}: WIP on feature-branch: abc1234 Add user validation
stash@{1}: On main: def5678 Experiment with caching
stash@{2}: On main: ghi9012 Debug logging

Because stashes are commits, you can use them anywhere Git expects a commit reference. This is what makes it possible to extract individual files, diff against them, or cherry-pick specific changes.

Method 1: Restore a File From Stash (Replace Working Copy)

This overwrites the file in your working directory with the stashed version:

bash
1# Using git restore (Git 2.23+)
2git restore --source stash@{0} -- path/to/file.txt
3
4# Using git checkout (all Git versions)
5git checkout stash@{0} -- path/to/file.txt

After running this, the file in your working directory matches exactly what was in the stash. Your other files are unaffected. The stash remains in the stack.

To restore multiple files at once:

bash
git restore --source stash@{0} -- src/config.py src/utils.py tests/test_config.py

To restore an entire directory:

bash
git restore --source stash@{0} -- src/components/

Method 2: View Changes Before Extracting

Before overwriting your working copy, you may want to see what the stash contains for that specific file.

Show the diff for a single file

bash
git diff stash@{0} -- path/to/file.txt

This shows the difference between the stashed version and your current HEAD. If you want to see the diff against your working directory instead:

bash
git diff stash@{0}..HEAD -- path/to/file.txt

Show the full content of the stashed file

bash
git show stash@{0}:path/to/file.txt

This prints the entire file content as it was when stashed. Useful for reviewing before extracting.

List all files modified in a stash

bash
git stash show stash@{0} --name-only
text
src/config.py
src/utils.py
tests/test_config.py

With stats:

bash
git stash show stash@{0} --stat
text
1 src/config.py       | 12 ++++++------
2 src/utils.py        |  8 +++++---
3 tests/test_config.py|  4 ++++
4 3 files changed, 15 insertions(+), 9 deletions(-)

Method 3: Apply Changes as a Patch (Merge, Not Replace)

git restore and git checkout replace the file entirely. If you want to merge the stashed changes into your current version of the file (preserving your current edits), create a patch and apply it:

bash
1# Generate a patch for a single file from the stash
2git diff stash@{0}^..stash@{0} -- path/to/file.txt > file.patch
3
4# Apply the patch to your working directory
5git apply file.patch
6
7# Clean up
8rm file.patch

The stash@{0}^..stash@{0} range compares the stash's parent (the commit the stash was created from) with the stash itself, giving you only the changes that were stashed.

If the patch conflicts with your current changes, git apply will fail. You can use --3way to attempt a three-way merge:

bash
git apply --3way file.patch

This creates conflict markers in the file that you resolve manually, similar to a merge conflict.

Method 4: Interactive Stash Apply With git stash pop -p (Partial)

If you want to interactively select which hunks from a stash to apply, you can use the patch mode. This does not limit to a single file but lets you pick individual change hunks:

bash
git stash show -p stash@{0} | git apply --index -p1

For applying only specific hunks, save the diff and use git apply with manual editing:

bash
git stash show -p stash@{0} -- path/to/file.txt | git apply

This applies only the changes to path/to/file.txt from the stash, as a patch against your current working directory.

Command Reference

TaskCommand
List all stashesgit stash list
List files in a stashgit stash show stash@{N} --name-only
View stashed file contentgit show stash@{N}:path/to/file
Diff stash vs HEAD for one filegit diff stash@{N} -- path/to/file
Extract file (replace)git restore --source stash@{N} -- path/to/file
Extract file (legacy)git checkout stash@{N} -- path/to/file
Apply stash changes as patchgit diff stash@{N}^..stash@{N} -- file > f.patch
Apply entire stashgit stash apply stash@{N}
Apply and drop stashgit stash pop stash@{N}

Working With Staged vs. Unstaged Changes in Stash

When you stash changes, Git captures both staged and unstaged modifications. By default, git stash show and file extraction commands see the combined result. If you stashed with --keep-index or want to distinguish between staged and unstaged parts, the stash commit structure matters:

  • stash@{0} is the working directory state (unstaged changes).
  • stash@{0}^2 is the index state (staged changes).

To extract only the staged version of a file:

bash
git restore --source stash@{0}^2 -- path/to/file.txt

This is rarely needed but useful when you stashed a mix of staged and unstaged work and want to separate them during extraction.

Common Pitfalls

Using git checkout stash@{0} -- file without first checking what the stashed version contains can overwrite uncommitted local changes. Always run git diff stash@{0} -- file or git show stash@{0}:file first to review the stash content.

Forgetting that git restore and git checkout replace the file entirely rather than merging changes leads to lost work. If your working copy has modifications you want to keep, use the patch approach instead.

Referencing the wrong stash index is easy when stashes accumulate. Run git stash list and verify the stash message before extracting. After you git stash drop an entry, all subsequent stash indices shift down by one.

Assuming git stash pop can target a single file is incorrect. pop always applies the entire stash. For single-file extraction, use restore, checkout, or the patch method.

Stashing without a message (git stash instead of git stash push -m "description") makes it difficult to identify the right stash later. Always include a descriptive message.

Extracting from a stash that was created on a different branch can introduce conflicts if the file has diverged. The patch approach with --3way handles this more gracefully than a direct file replacement.

Summary

  • Use git restore --source stash@{0} -- file to extract a single file from a stash.
  • Use git show stash@{0}:file to view the stashed file content before extracting.
  • Use git diff stash@{0} -- file to review changes before applying.
  • Use the patch approach (git diff stash@{0}^..stash@{0} -- file | git apply) when you want to merge stash changes with your current work instead of replacing.
  • Always verify the stash index with git stash list before extraction.
  • The stash is not dropped after extraction. Drop it explicitly with git stash drop when you no longer need it.

Course illustration
Course illustration

All Rights Reserved.