Save your changes temporarily in Git using Git Stash

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:

git commit history all branches

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:

git status with uncommitted changes

Now, let’s switch to master branch without making a commit. Run git status again. We’ll get something like below:

git status with uncommitted changes-2

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:

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:

status of working directory after stashing changes

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:

viewing existing changes from stash

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:

pop changes from stash

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:

apply chnages from stash

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:

try to git stash for untracked files

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:

Drop stashed changes in git

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.

create a new branch using git 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.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s