I had some uncommitted changes in my development branch and I stashed them using git stash
, but there were some changes which were very important among those stashed ones. Is there any way to get back those changes?
Also, I have made some changes on top of the stashed code files since.
Is there any chance I can retrieve the stashed changes to a new branch if possible?
The stash command takes the uncommitted changes in your working directory, both the updated tracked files and staged changes, and saves them. However, the changes aren't finished, and you need to switch to a different branch to quickly fix a bug before continuing on with the current feature.
To make this simple, you have two options to reapply your stash: git stash pop - Restore back to the saved state, but it deletes the stash from the temporary storage. git stash apply - Restore back to the saved state and leaves the stash list for possible later reuse.
What command should I use to retrieve my files that have been temporarilystashed ? R. - git stash popindex�What is the git command to see all the commit since 1st January 2017 ? R.
The stash list will be visible under the Stashes menu and right click will give the options to apply/delete/compare the changes. Apply Stash will show a popup to select git stash apply or git stash pop . Let me know if this has been useful in understanding the git stash command.
git stash apply
Just check out the branch you want your changes on, and then git stash apply
. Then use git diff
to see the result.
After you're all done with your changes—the apply
looks good and you're sure you don't need the stash any more—then use git stash drop
to get rid of it.
I always suggest using git stash apply
rather than git stash pop
. The difference is that apply
leaves the stash around for easy re-try of the apply
, or for looking at, etc. If pop
is able to extract the stash, it will immediately also drop
it, and if you subsequently realize that you wanted to extract it somewhere else (in a different branch), or with --index
, or some such, that's not so easy. If you apply
, you get to choose when to drop
.
It's all pretty minor one way or the other though, and for a newbie to Git, it should be about the same. (And you can skip all the rest of this!)
There are at least three or four different "ways to use git stash", as it were. The above is for "way 1", the "easy way":
This is the easy case, described above. Run git stash save
(or plain git stash
, same thing). Check out the other branch and use git stash apply
. This gets Git to merge in your earlier changes, using Git's rather powerful merge mechanism. Inspect the results carefully (with git diff
) to see if you like them, and if you do, use git stash drop
to drop the stash. You're done!
Now you want to keep, or even move, these changes, and apply your stash too.
You can in fact git stash save
again, as git stash
makes a "stack" of changes. If you do that, you have two stashes, one just called stash
—but you can also write stash@{0}
—and one spelled stash@{1}
. Use git stash list
(at any time) to see them all. The newest is always the lowest-numbered. When you git stash drop
, it drops the newest, and the one that was stash@{1}
moves to the top of the stack. If you had, even more, the one that was stash@{2}
becomes stash@{1}
, and so on.
You can apply
and then drop
a specific stash, too: git stash apply stash@{2}
, and so on. Dropping a specific stash renumbers only the higher-numbered ones. Again, the one without a number is also stash@{0}
.
If you pile up a lot of stashes, it can get fairly messy (was the stash I wanted stash@{7}
or was it stash@{4}
? Wait, I just pushed another, now they're 8 and 5?). I personally prefer to transfer these changes to a new branch, because branches have names, and cleanup-attempt-in-December
means a lot more to me than stash@{12}
. (The git stash
command takes an optional save-message, and those can help, but somehow, all my stashes just wind up named WIP on branch
.)
(Extra-advanced) You've used git stash save -p
, or carefully git add
-ed and/or git rm
-ed specific bits of your code before running git stash save
. You had one version in the stashed index/staging area and another (different) version in the working tree. You want to preserve all this. So now you use git stash apply --index
, and that sometimes fails with:
Conflicts in index. Try without --index.
You're using git stash save --keep-index
in order to test "what will be committed". This one is beyond the scope of this answer; see this other StackOverflow answer instead.
For complicated cases, I recommend starting in a "clean" working tree first, by committing any changes you have now (on a new branch if you like). That way the "somewhere" that you are applying them, has nothing else in it, and you'll just be trying the stashed changes:
git status # see if there's anything you need to commit # uh oh, there is - let's put it on a new temp branch git checkout -b temp # create new temp branch to save stuff git add ... # add (and/or remove) stuff as needed git commit # save first set of changes
Now you're on a "clean" starting point. Or maybe it goes more like this:
git status # see if there's anything you need to commit # status says "nothing to commit" git checkout -b temp # optional: create a new branch for "apply" git stash apply # apply stashed changes; see below about --index
The main thing to remember is that the "stash" is a commit, it's just a slightly "funny/weird" commit that's not "on a branch". The apply
operation looks at what the commit changed and tries to repeat it wherever you are now. The stash will still be there (apply
keeps it around), so you can look at it more, or decide this was the wrong place to apply
it and try again differently, or whatever.
Any time you have a stash, you can use git stash show -p
to see a simplified version of what's in the stash. (This simplified version looks only at the "final work tree" changes, not the saved index changes that --index
restores separately.) The command git stash apply
, without --index
, just tries to make those same changes in your working tree now.
This is true even if you already have some changes. The apply
command is happy to apply a stash to a modified working tree (or at least, to try to apply it). You can, for instance, do this:
git stash apply stash # apply top of stash stack git stash apply stash@{1} # and mix in next stash stack entry too
You can choose the "apply" order here, picking out particular stashes to apply in a particular sequence. Note, however, that each time you're basically doing a "git merge", and as the merge documentation warns:
Running git merge with non-trivial uncommitted changes is discouraged: while possible, it may leave you in a state that is hard to back out of in the case of a conflict.
If you start with a clean tree and are just doing several git apply
operations, it's easy to back out: use git reset --hard
to get back to the clean state, and change your apply
operations. (That's why I recommend starting in a clean working tree first, for these complicated cases.)
Let's say you're doing Lots Of Advanced Git Stuff, and you've made a stash, and want to git stash apply --index
, but it's no longer possible to apply the saved stash with --index
because the branch has diverged too much since the time you saved it.
This is what git stash branch
is for.
If you:
stash
, thengit stash apply --index
the attempt to re-create the changes definitely will work. This is what git stash branch newbranch
does. (And it then drops the stash since it was successfully applied.)
--index
(what the heck is it?)What the --index
does is simple to explain, but a bit complicated internally:
git add
(or "stage") them before commit
-ing.git stash
, you might have edited both files foo
and zorg
, but only staged one of those.git add
s the added
things and does not git add
the non-added things. That is, if you are add
-ed foo
but not zorg
back before you did the stash
, it might be nice to have that exact same setup. What was staged, should again be staged; what was modified but not staged, should again be modified but not staged.The --index
flag to apply
tries to set things up this way. If your working tree is clean, this usually just works. If your working tree already has stuff add
-ed, though, you can see how there might be some problems here. If you leave out --index
, the apply
operation does not attempt to preserve the whole staged/unstaged setup. Instead, it just invokes Git's merge machinery, using the working tree commit in the "stash bag". If you don't care about preserving staged/unstaged, leaving out --index
makes it a lot easier for git stash apply
to do its thing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With