To clear up the “Stash Fog,” you don’t have to guess what’s inside them. You can peek into the box before you open it.
1. List and Identify
First, see the list of what you’ve saved. If you didn’t name them, they’ll just have numbers.
Bash
git stash list
Output looks like: stash@{0}: WIP on feature/docker: fa84711 refactor variables... stash@{1}: WIP on main: 477e895 Merge pull request...
2. Inspect the Content (The “Peek”)
Before you apply a stash, see exactly what files were changed inside it:
- To see the file list:
git stash show stash@{0} - To see the actual code changes (the diff):
git stash show -p stash@{1}
3. Pop vs. Apply (The “Safety” Choice)
git stash apply stash@{0}: This takes the changes and puts them on your current branch but keeps a copy in the stash list. This is the safest way because if you mess up the merge, the data is still saved in the stash.git stash pop stash@{0}: This takes the changes, applies them, and immediately deletes them from the stash list.
Pro Tip: Always use apply first. Once you’re sure your code is working, then run git stash drop stash@{0} to manually delete it.
4. Resolving the Confusion: “Stash to Branch”
If your stash is a huge mess of changes and you’re afraid of applying it to your current branch and causing conflicts, you can turn the stash into its own new branch:
Bash
git stash branch feature/recovered-work stash@{0}
Git will create a new branch starting from the commit where you originally created the stash, apply the changes there, and drop the stash. This is the cleanest way to “un-confuse” your workspace.
Summary Checklist for a “Clean” Workspace
- Tag the points you want to save for “history.”
- Delete the local branches that show up in
git branch --merged. - Inspect your stashes with
git stash show -p. - Recover stashes into new branches if they are too complex to just “pop.”
To compare files in a Git stash, use the following commands depending on what you want to compare them against:
1. View changes within a stash
To see the full diff (patch) of the most recent stash relative to the commit where it was created:
git stash show -p- For a specific stash, append the index:
git stash show -p stash@{1}
2. Compare a stashed file to your working directory
To see the differences between a specific file in a stash and the version currently in your local folder:
git diff stash@{0} -- path/to/file- To compare all stashed files to your current working directory:
git diff stash@{0}
3. Compare two different stashes
To see the difference between two stashed states:
git diff stash@{0} stash@{1}
4. Compare a stashed file to a branch or commit
To see how a file in your stash differs from its version in another branch:
git diff stash@{0}:path/to/file main:path/to/file
Tips
- List Stashes: Use
git stash listto find the correct index (e.g.,stash@{2}) for the commands above. - External Tools: For a visual side-by-side comparison, use
git difftool stash@{0}if you have a tool like Meld or Beyond Compare configured. - Summary Only: If you only want to see which files changed without the code diff, use
git stash show(defaults toshowStat).
Important Usage Tips
- Shell Escaping: If you are using PowerShell or certain Unix shells (like Zsh), the curly brackets may need to be quoted to prevent the shell from interpreting them:
git diff "stash@{0}" "stash@{1}" -- ./lib/math/math_utils.sh
- Comparison Order: Git shows the changes needed to turn the first revision into the second.
stash@{0}is your most recent stash.stash@{1}is the stash before that one.
- Path Separation: The
--(double dash) is recommended to explicitly separate the stash references from the file path, especially if the file name could be mistaken for a revision.
What’s stored in git stash?
git stash does not store every file in your repository by default.
It only stores your uncommitted changes.
Specifically, it captures a snapshot of the following:
- Staged changes: Files you have already added with
git add. - Modified tracked files: Files already in your repository that have unstaged edits.
What is EXCLUDED by default?
- Untracked files: New files that have never been added to the repository are ignored.
- Ignored files: Files listed in your
.gitignoreare also ignored.
How to include everything
If you want to stash more than just the modified files, you must use specific flags:
- Include untracked: Use
git stash -u(or--include-untracked) to include new files that aren’t yet tracked. - Include everything: Use
git stash -a(or--all) to include untracked files and ignored files (like build artifacts or logs).
How it works internally
Internally, Git creates commits to represent your stash. Each stash entry is actually a set of two (or three) special commits that store your index and your working directory state at that moment. Because these are stored as commits, they use Git’s de-duplication: they only “save” the data for files that have actually changed.
When you run git diff stash@{0} stash@{5} -- path/to/file, Git compares the state of that file as it exists in those two specific stash “commits.”
If math_utils.sh was not modified in stash@{5}, Git compares the file in stash@{0} to the original version of the file that existed in the repository when stash@{5} was created.
Key Details
- The Full File State is Compared: A stash is internally stored as a set of commits that represent the entire index and working tree at the time of stashing. Even if a file wasn’t “dirty” (modified) when you ran the stash command, the stash still knows what that file looked like in the repo at that moment.
- What You Will See:
- If
math_utils.shinstash@{0}is different from how it existed whenstash@{5}was made, you will see a diff showing those changes. - If the file in
stash@{0}is identical to how it existed whenstash@{5}was made, the command will return no output.
- If
Why this happens
When you create a stash, Git takes a snapshot of your entire working directory’s state. For files that were not modified, it simply references the version of the file from the commit you were on (the HEAD) at that time. Therefore, your command is essentially comparing the modified version in your recent stash against the “clean” version that existed in the repository history at the time of your 5th stash.
How to find which branch stash was created by:
Yes, you can identify the branch a file was on when stashed by inspecting the stash’s metadata.
1. View the Branch in the Stash List
The most straightforward way is to use the list command. By default, Git includes the branch name in the stash message:
git stash list
Example output:stash@{0}: WIP on master: 6ebd0e2... Update docsstash@{1}: On feature-branch: My custom message
The text following “WIP on” or “On” (e.g., master or feature-branch) is the branch that was active when that stash was created.
2. Check the Branch for a Specific Stash
If you only want the branch info for a specific index without scrolling through a long list, you can use git show on the stash’s reference:
git show --format="%gs" -s stash@{0}
--format="%gs": This extracts the “reflog subject,” which for stashes contains the branch name (e.g., “WIP on main”).-s: Suppresses the actual file diff so you only see the branch/message.
3. Find Branches that “Contain” the Stash
Because a stash is technically a commit, you can find which branches currently “contain” its base commit. This is useful if the branch name in the stash message has been deleted or renamed:
git branch --contains stash@{0}^
stash@{0}^(with the caret): This points to the parent commit of the stash (the exact point in history where you were standing when you ran the stash command).- This will return a list of all branches that grew out of that same commit.
Important Limitation
Git stashes the state of the entire working directory at once, not file-by-file. Therefore, you cannot find different branches for different files within the same stash entry—every file in stash@{0} was on the same branch at the time of stashing.
Can you add comment and/or name a stash?
Yes, you can add a custom message or name to a stash to make it easier to identify later.
1. Add a name when creating a stash
The modern way to add a descriptive note is using the -m (or --message) flag with git stash push.
git stash push -m "Your custom message here"
- Tip:
git stash save "message"is an older, deprecated command. You should usegit stash push -min 2026 as it is more robust and allows you to stash specific files if needed. - Shorthand: You can also use
git stash -m "message"as a shortcut.
2. Viewing your named stashes
To see your notes, use the list command:
git stash list
Output Example:stash@{0}: On main: Your custom message here
3. Rename an existing stash
Git does not have a direct rename command for stashes. To change a message on an existing stash, you must “drop” it and then “store” it again with the new message:
- Find the index (e.g.,
stash@{1}) usinggit stash list. - Drop the stash and copy the SHA hash it returns:
git stash drop stash@{1} - Re-store it with the new message using that SHA:
git stash store -m "New message" <SHA>
4. Retrieve a stash by its name
You can use a regular expression to apply or pop a stash based on its custom message:
- Apply:
git stash apply stash^{/Your custom message} - Pop:
git stash pop stash^{/Your custom message}
Note: Be exact with the text inside {/ } to avoid matching multiple stashes.
