Use the following to apply the changes to a file in a stash to your working tree.
git diff stash^! -- <filename> | git apply
This is generally better than using git checkout
because you won't lose any changes you made to file since you created the stash.
If the stashed files need to merge with the current version so use the previous ways using diff. Otherwise you might use git pop
for unstashing them, git add fileWantToKeep
for staging your file, and do a git stash save --keep-index
, for stashing everything except what is on stage.
Remember that the difference of this way with the previous ones is that it "pops" the file from stash. The previous answers keep it git checkout stash@{0} -- <filename>
so it goes according to your needs.
The simplest concept to understand, although maybe not the best, is you have three files changed and you want to stash one file.
If you do git stash
to stash them all, git stash apply
to bring them back again and then git checkout f.c
on the file in question to effectively reset it.
When you want to unstash that file run do a git reset --hard
and then run git stash apply
again, taking advantage ofthe fact that git stash apply
doesn't clear the diff from the stash stack.
$ git checkout stash@{0} -- <filename>
Notes:
Make sure you put space after the "--" and the file name parameter
Replace zero(0) with your specific stash number. To get stash list, use:
git stash list
Based on Jakub Narebski's answer -- Shorter version
To see the whole file: git show stash@{0}:<filename>
To see the diff: git diff stash@{0}^1 stash@{0} -- <filename>
You can get the diff for a stash with "git show stash@{0}
" (or whatever the number of the stash is; see "git stash list"). It's easy to extract the section of the diff for a single file.
Edit: See cambunctious's answer, which is basically what I now prefer because it only uses the changes in the stash, rather than comparing them to your current state. This makes the operation additive, with much less chance of undoing work done since the stash was created.
To do it interactively, you would first do
git diff stash^! -- path/to/relevant/file/in/stash.ext perhaps/another/file.ext > my.patch
...then open the patch file in a text editor, alter as required, then do
git apply < my.patch
cambunctious's answer bypasses the interactivity by piping one command directly to the other, which is fine if you know you want all changes from the stash. You can edit the stash^!
to be any commit range that has the cumulative changes you want (but check over the output of the diff first).
If applying the patch/diff fails, you can change the last command to git apply --reject
which makes all the changes it can, and leaves .rej
files where there are conflicts it can;r resolve. The .rej
files can then be applied using wiggle
, like so:
wiggle --replace path/to/relevant/file/in/stash.ext path/to/relevant/file/in/stash.ext.rej
This will either resolve the conflict, or give you conflict markers that you'd get from a merge.
Previous solution: There is an easy way to get changes from any branch, including stashes:
$ git checkout --patch stash@{0} path/to/file
You may omit the file spec if you want to patch in many parts. Or omit patch (but not the path) to get all changes to a single file. Replace 0
with the stash number from git stash list
, if you have more than one. Note that this is like diff
, and offers to apply all differences between the branches. To get changes from only a single commit/stash, have a look at git cherry-pick --no-commit
.
If you use git stash apply
rather than git stash pop
, it will apply the stash to your working tree but still keep the stash.
With this done, you can add
/commit
the file that you want and then reset the remaining changes.
Source: Stackoverflow.com