Git Stash to the Rescue
Learn what to do when you suddenly realize you've been making changes on your master branch.
We’ve all been there. You’re working hard on your code, creating features, trying new styles – and then you notice something. You forgot to move to a feature branch and you’re making changes directly on master. You don’t want to continue working on master, but it seems way too complicated to try to copy/paste all your changes. And you certainly don’t want to lose all the hard work you’ve done.
Good news! Git has a useful feature called
git stash. Think of
git stash as a way of storing all your changes in a
basket that can be stored away for later use. The git documentation describes it this way:
git stashwhen you want to record the current state of the working directory and the index, but want to go back to a clean working directory. The command saves your local modifications away and reverts the working directory to match the
There are many uses for
git stash, but in this tutorial we will focus on the case of rescuing unintended changes to
master. Please note that
git stash can only be used to save changes if they are in fact only modifications to master and not commits.
However, if you do accidentally make a commit (or a few) to the master branch, I have also included a backup plan for
you at the end. All is not lost.
How to Use Git Stash
Rescuing uncommitted changes on a branch is actually a very easy fix.
- You first use
git stashto gather and store all the changes in a neat little package.
- Then use
git checkout <new-branch-name>to create and switch to a new branch.
- Lastly, use
git stash popto simultaneously remove the changes from your stash and then pop them onto the new branch.
In the repository below, I am planning a garden. I start making changes to
layouts.md and then see
that I forgot to make my feature branch and am still on master. I then use
git status and see that I do in fact
have a modified file.
As you can see in the screenshot below, I use
git stash to stash my changes. Then for the sake of
the tutorial I also run
git status to show you that I do have a clean working directory. The changes
are off master and stashed away.
I then checkout a new branch and run
git stash pop to put all those changes on the new branch. As you
can see, the modified
layouts.md file is now in the new branch.
There’s one last little note about
git stash for now. It will stash any files that are already being tracked
whether staged or unstaged. However, it will not stash any new files that have been created. If you want to stash new
untracked files, you will need to use a
-u flag like this:
git stash -u.
Let’s say I create a new file called
supplies.md before I realize I’m on master. If I run
git stash and then run
status again to make sure the changes have been stashed, see what happens:
The new file is still on master. But if I run
git stash -u, which stashes even new and untracked files, the new file
will then be stashed.
I can then pop the changes into a new branch.
Let’s say you didn’t realize you were making changes on the master branch until you already have made one or more
commits to the master branch. In this case,
git stash will not work. Instead, you will need to use
git reset --hard. I’ll
explain through an example.
(Commit1) --- (Commit2) --- (Commit3) --- (Commit4) --- (Commit5) Last intended head master commit
The last intentional commit on master was at commit 3, but now you’ve made 2 more commits and you’re on commit 5. Before we set everything right, make sure that everything is committed and there are no unstaged or staged changes.
For our example, let’s pretend I have a repository about Harry Potter. So far my master branch has 3 files. I can use
git reflog to see my commit history. The most recent commit is on top.
While still on master, I forget to create a new branch to add more characters to
characters.html and instead just
open the file and start adding to it. I add one character and make a commit, then I add another character and make a commit.
Oops! I’m still on master, but I’ve now made 2 commits that I shouldn’t have. The commits about Luna and Hermione should
be on a separate branch, not master.
Now, the first step is to create a new branch off of my current commit. This duplicates the master branch as it is so that I am able to pick up where I left off on the new branch as if it were there all along.
add-characters branch looks exactly like master. (Note: the
add-characters branch has been created, but I’m still on
master, which is important for the next step.) Now I want master to reset back to where it was before I made
the changes. We can accomplish this with
git reset –hard <commit>, where “commit" is the hash of the commit that should be
last on master. The hash number can be found with
git reflog. In this example, we can look back and see that the commit
with the message “Add initial hogwarts facts" is the last commit before the changes and has a hash of 9f993aa.
HEAD back to the specified commit as if the new commits on master never happened.
Above, you can see I found the hash of my target commit with
git reflog. I then reset master back to that commit and
received the message that
HEAD is now at the original commit.
Now when I checkout the
add-characters branch, everything is there as I left it and I can continue coding in this
branch as if it was that way all along.
There you have it. Now you know how to save your work when you find yourself making changes on master whether you
have already made commits or not. Of course the goal is to always move to a feature branch before making changes,
but mistakes happen and it’s great that git has provided ways to rectify them. You have
git stash and
--hard in your git toolbelt. Use them wisely and keep on coding!
I found the following resources most helpful for creating this tutorial:
There’s much more to
git stash if you’re interested, like saving with a message, saving multiple
stashes, checking a list of stashes, applying only specific stashes. This is a helpful article that can give you a
slightly more indepth introduction to stash: