This happens almost every now and then. You are in middle of working on some code changes, modified few files here and there and may be added new files. Now something else comes up urgently and you are asked to do it now. But you do not want to make a commit in middle of the work. In such a case, if you switch branch, your changes are carried over to the another branch as well. So you need a way to save your work temporarily. Fortunately, Git allows this functionality using what is known as Git Stash.
Stashing takes the dirty state of your working directory — that is, your modified tracked files and staged changes — and saves it on a stack of unfinished changes that you can reapply at any time.
Demonstration of the Problem
Let’s consider below state of the two branches in one of the Git repos, we are having:
As you can see, we are now in the master branch, couple of commits behind the branch newQuickFix. Let’s switch to newQuickFix branch, modify couple of files, so that our status looks like:
Now, let’s switch to master branch without making a commit. Run git status again. We’ll get something like below:
So, even before we start to work in the newly switched branch, we have changes that we do not need.
Save changes using Git Stash
Let’s switch back to newQuickFix branch since that is where we made the changes and that’s where we should save the changes. Before that, we need to run git add command to make sure our changes are promoted to staging area. After this, we can run git stash command:
At this point, if we run git status command to get status of the working directory, we would be greeted with below message:
Hurray! Now you can easily switch branches and do work elsewhere; your changes are stored on your stack.
View if any changes are already stashed
For this, we can use the git stash list command:
If we have applied stash one or more times, we could see that as well. The latest stash you created is stored in refs/stash; older stashes are found in the reflog of this reference and can be named using the usual reflog syntax (e.g. stash@{0} is the most recently created stash, stash@{1} is the one before it, stash@{2.hours.ago} is also possible). Stashes may also be referenced by specifying just the stash index (e.g. the integer n is equivalent to stash@{n}).
Re-applying your stashed changes
You can reapply previously stashed changes with git stash pop:
Popping your stash removes the changes from your stash and reapplies them to your working copy.
Alternatively, you can reapply the changes to your working copy and keep them in your stash with git stash apply:
This is useful if you want to apply the same stashed changes to multiple branches.
Note that both git stash pop and git stash apply command applies only to latest stashed set of changes.
Also note that, you can have modified and uncommitted files in your working directory when you apply a stash — Git gives you merge conflicts if anything no longer applies cleanly.
Now that you know the basics of stashing, there is one caveat with git stash you need to be aware of: by default Git won’t stash changes made to untracked or ignored files.
Stashing untracked or ignored files
By default, running git stash will stash:
1. Changes that have been added to your index (staged changes)
2. Changes made to files that are currently tracked by Git (unstaged changes)
And, it will not stash:
1. New files in your working copy that have not yet been staged
2. Files that have been ignored
So if we add a third file to our example above, but don’t stage it (i.e. we don’t run git add), git stash won’t stash it:
To overcome this, we have 3 options:
1. Adding the -u option (or –include-untracked) tells git stash to also stash untracked files.
2. Include changes to ignored files as well by passing the -a option (or –all) when running git stash.
3. Run git add file1 file2 .. or git add . to add files to staging area
Drop git stash
For some reason, you dont want to apply changes from git stash and you want to drop it. In such a case, run git stash drop command:
This is also useful, if you have earlier run git stash apply command.
Creating a branch from your stash
As mentioned earlier, if the changes on your branch diverge from the changes in your stash, you may run into conflicts when popping or applying your stash. Instead, you can use git stash branch to create a new branch to apply your stashed changes.
This checks out a new branch based on the commit that you created your stash from, and then pops your stashed changes onto it.