Partial, half-baked, or otherwise incomplete work is inevitable in the lifespan of a developer. Fortunately, git offers a few ways out-of-the-box to manage temporary work you’re not quite ready to commit.
First, a few definitions:
- Stash – a unit of temporarily uncommitted/staged changes
- Pop – apply a stash and delete the stash
- Apply – apply a stash and keep the stash
We’ll run through a couple scenarios to cover some different possibilities. If you have any specific scenarios you want to address, feel free to comment below or get in touch!
Most of your scenarios will involve some kind of change: commits, staged files, etc followed by the need to temporarily stash your work. You can hold onto as many stashes as you want, and you can even name them to give your future self some context of what you were doing.
I made some changes, now I need to switch gears
Let’s say your current diff looks like this:
Then, along comes a request to work another feature or the need to fix a bug. But alas, we don’t want to lose our insanely complex and tireless work to the ether! Enter git stashes.
Hop on over to Team Explorer in Visual Studio. If you don’t have this pane available, click View => Team Explorer in Visual Studio’s menu. Team Explorer should describe your current situation i.e. existing changes and unstaged files. If you enter some text into the commit message before this next step, the stash will have a name. In this example, we’re going to use the message “complex changes” to describe our stash.
After you’ve set the stash’s name, Click the Stash dropdown menu, and click Stash All. Your stash has been created, and it even has a name.
You’ll also notice there are no more changes in your working directory. Git cleans those up after stashing, so you can complete other operations e.g. pulling the latest code to work an emergency bug.
Fast forward–now you’ve resolved the emergency bug, and you want to get back to working your complex changes. The cleanest option is to pop the stash. Alternatively, you could apply the stash. The difference is whether or not git deletes the stash afterward. We’re going to pop the stash, since we don’t care about keeping it around.
In Team Explorer, right-click the stash, hover over Pop, and click either option. The screenshot above has Pop All as Unstaged selected, but it doesn’t matter in this scenario since we didn’t have anything staged.
Visual Studio will make your stash’s changes on disk, and you should notice the changes in the Changes section of Team Explorer. If you still had your file open, you might even visually confirm the changes were applied.
Voila! The simplest scenario of stashing and popping.
In addition, git stashes can maintain the staged and unstaged state of files. The Stash dropdown menu and the right-click menu to pop/apply has multiple options to handle these cases. Remember the Stash All and Keep Staged option from earlier? Selecting that option while you have staged files will maintain their staged state when popping or applying the stash later. Try out some different scenarios to see how you can manage different workflows!
I made changes related to different work items–help!
This happens. You’re working on one work item (a feature, etc) then you get sidetracked with another issue, you’ve made changes to several different files, and now you need to separate the work by making separate stashes. Unfortunately thus far, I’ve come up empty with a solution to handle this within the Visual Studio 2019 GUI. This has to be done via command line with:
git stash save -p "stash message"
For what it’s worth, Visual Studio hangs when I run the above command in Package Manager Console (a terminal within Visual Studio,) so I ran this at a PowerShell prompt to make it work.
There’s a great StackOverflow answer here that gives you a high-level overview of how to use that command. If you happen to find an extension for Visual Studio 2019 that helps with this, I’d love to hear about it!
I’ve included some summary screenshots of running this command.
A note about the [master] notation: I have installed posh-git. It’s a great module that enhances your prompt to describe the state of a git repository. It’s not required, but if you’d like to install it, check this out.
First, run the command above:
git stash save -p "stash message". Git will analyze your changes and give you a set of acceptable actions in the form of single-letter responses. In my case, I can answer
[y,n,q,a,d,e,?], so I decide to get help with
?. You can use this option at any time during the operation to get a sense of what those single letters mean.
A hunk is a segmented change as git has interpreted it. We don’t have any changes large enough to necessitate (s)plitting in this scenario, but I think git will allow splitting of hunks all the way down to a single line. Worst case, you can answer
e to manually edit the current hunk.
After I ask for help, git presents me with the same change again. This change is the addition of a line to my .csproj file, which I don’t want in this stash, so I answer
n. I do want to stash the next change in Program.cs, so I answer
y and press enter. At this point, git saves the stash, and it only includes the changes to Program.cs. Team Explorer has already updated to indicate there’s a stash called “stash message” and reviewing that stash confirms the changes were limited to just one file instead of the other changes as well.
At this point, we could branch, wipe out these changes, create another partial stash, pretty much anything. Git is really powerful at the command line, but I guess the Visual Studio extensions are still playing catch up!