The Git Stash Command

When working on a project using Git, there may be occasions where you’ll need to save your local modifications for later. This is where the git stash command can be used.

Imagine you’re working on a feature branch that will add some functionality to your project. All of sudden you need to work on a hotfix to solve a bug that’s just been raised. If you are part of the way through your feature branch work and are not ready to commit the changes, you can use git stash.

To demonstrate an example, imagine you have a simple project that contains a index.html and a css/styles.css file that have both been committed previously.

Running a git status would show the following.

$ git status
On branch master
nothing to commit, working directory clean

Now let’s assume that you are working on a feature branch that belongs on a feature/some_custom_work branch.

The modifications being made on this branch involve changes within the styles.css file. Running another git status shows:

$ git status
On branch feature/some_custom_work
Changes not staged for commit:
  (use "git add ..." to update what will be committed)
  (use "git checkout -- ..." to discard changes in working directory)

	modified:   css/styles.css

no changes added to commit (use "git add" and/or "git commit -a")

Git has recognised that this file has been modified. Supposing a high priority bug fix needed to be fixed right away. The bug fixes involves making changes to styles.css, however you don’t want to commit your current feature branch changes, nor do you want to revert the file back to its original state. The answer? Run git stash to save your changes locally.

$ git stash
Saved working directory and index state WIP on feature/some_custom_work: 61f7761 Initial commit
HEAD is now at 61f7761 Initial commit

Now running git status will show the working directory to be clean.

$ git status
On branch feature/some_custom_work
nothing to commit, working directory clean

Your feature branch changes have been successfully stashed ready to be worked on later. To re-apply your stashed changes, run the git stash pop command.

$ git stash pop
On branch feature/some_custom_work
Changes not staged for commit:
  (use "git add ..." to update what will be committed)
  (use "git checkout -- ..." to discard changes in working directory)

	modified:   css/styles.css

no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (fc7ba40435d2b90976ad903a85028b08fbaf9977)

By default, Git will not stash untracked files. This means that if you were to create new files to your feature work branch, such as a styles-2.css, unless you were to track this file in Git, it would not be stashed!

Running a git status that includes an untracked file might look like the following.

$ git status
On branch feature/some_custom_work
Changes not staged for commit:
  (use "git add ..." to update what will be committed)
  (use "git checkout -- ..." to discard changes in working directory)

	modified:   css/styles.css

Untracked files:
  (use "git add ..." to include in what will be committed)

	css/styles-2.css

Running git stash would stash styles.css.

$ git stash
Saved working directory and index state WIP on feature/some_custom_work: 61f7761 Initial commit
HEAD is now at 61f7761 Initial commit

But not styles-2.css

$ git status
On branch feature/some_custom_work
Untracked files:
  (use "git add ..." to include in what will be committed)

	css/styles-2.css

nothing added to commit but untracked files present (use "git add" to track)

There are a couple of methods to resolve this. Track the file(s) by using git add.

$ git add css/styles-2.css

You can also pass in a -u argument to the git stash command to include untracked files.

$ git stash -u

And finally, you can view a summary of a stash by running git stash show.

$ git stash show
 css/styles.css | 36 +
 css/styles-2.css | 16 +
 1 file changed, 1 insertion(+)