The Git Stash Functionality in Visual Studio 2019Thomas Claudius Huber
If you have looked already at the Changes page of Team Explorer in Visual Studio 2019, you might have seen that it has a new Stashes section. It is shown in the screenshot below. But for what is that Stashes section?
Let’s say you are working on a feature. But you’re not ready to commit it, as you didn’t reach yet the code quality you normally write. But you want to save the functionality for now and look at the original branch without changes. To do this, you can stash the changes.
Just enter a message in the Changes window of Team Explorer. The message is optional for a stash, I entered in the screenshot below the message “First draft of customer login”. Now click on the Stash button:
From the drop down, click on “Stash All”. This will create a stash that contains all the uncommitted changes. So, a stash is like a local copy of your uncommitted changes. Clicking on “Stash All” will also undo all those uncommitted changes in your branch. If you want to keep the changes in the branch that you have already staged for a commit, you select “Stash All and Keep Staged”. But in my case above, I haven’t staged the Program.cs file. So both stash options will have the same effect. Let’s select “Stash All”.
After clicking on “Stash all”, you can see now the created stash, and the branch doesn’t have any changes anymore.
Now you can switch for example to another branch. Later you can come back to your feature branch, and there you can right-click on that stash in the Changes page of Team Explorer. From the context menu that you get then (you can see it below) you can view the changes. Instead of using the context menu to view the changes, you can also double-click the stash.
As you can see in the picture above, beside the “View Changes” menu the context menu of the stash has also the following options:
- Apply – this will apply the changes to the branch and it will keep the stash
- Drop – this will delete the stash
- Pop – this will Apply the changes and Drop the stash
Under the menu items Apply and Pop you find two options. You can see them in the screenshot above for the Pop menu:
- Pop/Apply and Restore Staged – this will pop/apply the changes to your branch and it will also ensure that files that you had staged before are staged again
- Pop/Apply All as Unstaged – this will pop/apply the changes to your branch and it won’t stage the files that you had staged before.
If you hadn’t any staged files before you created the stash, then you won’t see a difference between the two options. So let’s select in my case “Pop All as Unstaged”, and then we’re back at the state that we had at the beginning of this blog post. A change in the Program.cs file:
So, stashing is great for storing changes that you do not want to commit yet.
Another thing where stashing is quite useful is when you want to switch to another branch. This works without a problem if the other branch points to the same commit as the branch that you’ve checked out. But if the other branch doesn’t point to the same commit, you have to commit your local changes first to checkout the other branch. But what if you are not ready yet to commit? Instead of undoing or committing your changes, you can also stash them, and this is what Visual Studio actually suggests when you try to checkout another branch and the other branch points to another commit and you have made local changes that you haven’t committed yet (yes, I know, a lot of conditions in this sentence. :-)).
Let’s see this in action. As you saw in the screenshot above, I have made changes to the Program.cs file. In the picture below you see the branches page of Team Explorer. The checked out branch feature/customerLogin has local changes, and it also does not point to the same commit as the master branch (You can’t see that in the screenshot, so just believe me :)). So let’s see what happens when we try to checkout the master branch by using the context menu like below:
Visual Studio notices the problem and shows this window:
In this window you can do a force checkout, which means Visual Studio will undo the local changes and checkout the master branch. That means your uncommitted changes will be lost. But Visual Studio shows you another dialog after clicking on “Force Checkout” to ensure that you’re really sure to undo your local changes.
Instead of doing a force checkout, you can also click on “Stash and Continue”. This will stash your uncommitted changes from the feature branch, it will checkout the other branch, which is in this sample the master branch. Then it will apply the changes from the stash to the master branch. If you don’t want to apply the changes to the master branch, you should click “Cancel” in this dialog. Then create a stash manually like shown in this blog post, and after that you can checkout the master branch smoothly, as you won’t have any uncommitted local changes anymore after you created the stash.
Btw., when applying a stash, you can get conflicts in a way like when merging a branch. You can solve these conflicts exactly with the same options that you know from merging branches. You have options like merge, take theirs, or take yours.
I think for most developers branching is enough. But stashing is a powerful and popular git feature to store some local changes that you don’t want to commit yet. And now we have it integrated in Visual Studio.
If you want to learn more how to use Git in Visual Studio 2019, check out my Pluralsight course Using Git for Source Control in Visual Studio 2019. It shows you how to commit, push, and pull changes, how to work with branches and tags, how to handle pull requests in Visual Studio, and how to view the history of your code.
I hope this helps.
Thank you so much for an article that explains this concept in a very straightforward manner. As a long time TFS user and new to Git, I’ve had a difficult time finding explanations that made sense. Prost!
Thanks Dan, great to read it was helpful
Nice feature and great article describing the feature. Earlier needed to go to git CLI and manage stashing from there but now it is available in IDE itself. Thanks
Great job and very timely for me! Thank you, Thomas, for taking the time to post this! Kudos!
I am from SVN background, and in a project, I have to work with Git. With SVN, I am using Tortoise SVN client, and with a Visual Studio plugin named Ankhsvn, everything works smoothly without having to know a single SVN command, this is productive. When I was first introduced to Git, this makes me struggle for some time, and a lot of time being spent to investigate what’s the similar Git tool for Visual Studio, this article comes into rescue, but of course, I have some little know-how already about Git pull, push, and stash, but I didn’t realize that the Team Explorer would be that helpful.
Thanks for the effort by writing this easy to follow article! By the way, I reach here by Googling ‘Stash All VS Stash All and Keep Staged’. ;)
Thanks for the feedback. Happy to read it was helpful.
Is it possible to push a stash to the shared GIT server?
I’ve got a huge bunch of changes that I’ve made on the master branch on my work machine. I’d like to stash them and then push the stash to the shared GIT server so that I can go home, pull all the code and then un-stash.
Is this possible?
it is kind of possible, but stash is more meant as a local functionality. If you want to push it to the server, I recommend to work with branches. Create a branch with your local changes, push it to the server, and check it out at home.
I hope this helps,
Nice One. I was looking for the GitStash extension and could not find that. Did not realize until now that 2019 has this inbuilt.
Yes, it’s really nice to have this feature inside Visual Studio.
People learning git will stash, then panic and think their work from yesterday all disappeared overnight.
Why do you think that people learning git will directly stash? From what I’ve seen, most git newbies don’t stash.
Thanks! Good explanation and easy to understand
Thank you Sri, happy to read that you like it!
Thanks for your really nice article (-:
You’re welcome! :-)
As a fairly new coder I get anxiety when I need to do things with Visual Studio that I’m unfamiliar with. I don’t want to mess it up! Stashing has been one of those gray areas. The documentation helps but it still can be so specific that it comes across as ambiguous. (contradiction, i know). Your post gave me the clarity and peace of mind that I needed to “just do it!” (Sorry Nike). I’ve been stashing like a champ ever since!
Thank you Matthew, happy to read that you’re stashing like a pro after reading this blog post.
Thanks for the post.
I’ve used stashing before, but it can become a mess very quickly when moving in and out of branches, especially if you are working on say several solutions at the same time.
For some reason VS is now automatically adding some of my changes to Stash and some to Changed. This is ultimately confusing about what is being committed and not. Files added dont appear to be added to Git now either, I have to manually add them which is breaking the build server if the files are forgotten to be added.
I find on the whole, the vernacular used in GIT is non-intuitive and all over the place. Push, pull, fetch, pop, stash, force and so on…. What was already a messy scenario for new developers to wrap their heads around, just became even more confusing. It would be far easier to option these types of features in settings somewhere – if someone wants to stash, let them turn it on. As a software company owner, I dont want my dev’s stashing code on local repos – the amount of work we have lost due to machines dying over the years is staggering.
So this just appears to be another option, that developers created, turn on by default, without really understanding all the implications, especially in the context of professional development.
Thanks for the article. I appreciate the time and effort you took to share your knowledge.
First, glad to see stashing is now in VS.
How about adding “shelve” functionality like Team Foundation?
Shelve has two features that are very nice and do not exist in git.
1. Shelve will only shelve the “included” changes. In git, the closest is the “staged.” Sometimes I want to archive a modification so I can finish committing some other changes. This is a real hassle to do with git. You have to think backwards (stage the files you do want to commit, stash all files with keep index, apply (not pop) the stash you just created, undo the non-staged files, commit, pop the same stash).
2. Shelvesets are server-side. Stashes are client-side. Sometimes you want to share some files with someone else or just a different computer. Would be nice if VS could add some special “shelveset” branch and push commits to it when “shelving”
I would say with git branches we don’t need shelvesets. You can always create a branch after you changed the code, and then just push to that branch.
Is it possible to stash just a single file ?
I’m also looking for the option to stash individual or selected files. I know I can do that by creating reverting other changes or pushing to another branch and then stashing what’s left, but something like:
git stash push -m welcome_cart app/views/cart/welcome.thtml
…would be a really useful next addition to VS Git Commands :)
Can you explain how to see stashed files from other developer in the team?
Hi Jannatul, that’s possible with a patch file, and you can read about it here: https://stackoverflow.com/questions/3973034/export-a-stash-to-another-computer
But sharing a stash is not the idea of a stash. Usually I create and push a branch if I want to share with other developers. A stash is only something I use for me locally.
Hi, is it possible to retrieve a deleted stash in Visual Studio Git? Also does the stash get physically stored on the disk somewhere? If so, could you please let me know the default path where it gets stored? (just in case I want to have a physical backup copy of all the stashed files)
Your Pluralsight video on this topic helped me more than once! Regarding the window above when checking out master while in a feature branch “The following unsaved or uncommitted files are preventing the checkout operation” .
This stopped prompting me when I made a change and it appears under “Changes”. I’m not clear why?
Maybe you had an unsaved file, and after the change you saved it, and it didn’t prompt anymore?