Stashing Work In Progress

References:

Now that you are comfortable with branching, we will explore the git stash command.

Create a new branch for a new feature:

[1]$ cd ~/repos/example
[2]$ git checkout -b feature/foo master
[3]$ git branch

Make another change to the hello file:

[4]$ echo '# Adding the "foo" feature' >> hello
[5]$ git status
[6]$ git diff

Time goes by and you have made a bunch of changes, but you have not added your changes and you are not ready to commit your work in progress.

Then your boss comes by and tells you to work on Jira ticket AA-1234. Obviously, you don’t want to work on the ticket in the feature/foo branch or on the master branch, but on its own branch. Let’s try switching to a new branch for the ticket:

[7]$ git checkout -b feature/AA-1234 master
[8]$ git status
[9]$ git diff

Notice that our pending change got carried over to the new branch. That’s not want we wanted. Switch back to the feature/foo branch:

[10]$ git checkout feature/foo

What we need to do is stash away the changes on the feature/foo branch:

[11]$ git stash save 'wip: new foo feature'
[12]$ git stash list
[13]$ git stash show -p

Since the changes to feature/foo are safely stashed away, we can switch to the feature/AA-1234 branch and work on that change:

[14]$ git checkout feature/AA-1234
[15]$ git status
[16]$ sed -e '/^exit/s/exit 0/exit 1/' hello > hello.tmp
[17]$ mv hello.tmp hello
[18]$ git status
[19]$ git diff

At this point, you get blocked on the Jira ticket, and want to jump back to the feature/foo. Just stash the work in progress on the feature/AA-1234 branch:

[20]$ git stash save 'wip: fix for AA-1234'

You should now see two stashes:

[21]$ git stash list
stash@{0}: On feature/AA-1234: wip: fix for AA-1234
stash@{1}: On feature/foo: wip: new foo feature

Switch back to the feature/foo and put the stashed changes back in place:

[22]$ git checkout feature/foo
[23]$ git stash pop stash@{1}
[24]$ git stash list
[25]$ git status
[26]$ git diff

Commit the changes for feature/foo:

[27]$ git add hello
[28]$ git diff --cached
[29]$ git commit

Now that we’re done with adding the feature/foo branch, we can go back to the feature/AA-1234 branch and commit the stashed changes there:

[30]$ git checkout feature/AA-1234
[31]$ git stash list
[32]$ git stash pop
[33]$ git diff
[34]$ git add hello
[35]$ git commit

Both the feature/foo branch and the feature/AA-1234 branch are ready to be merged into the master branch.

Note

Students should now merge both branches into master as an exercise. You should expect merge conflicts.

Warning

It is not a good idea to leave things in the stash for very long. It’s better to push to a WIP branch on a remote server (more on that later). Best practice is to only stash changes for a minimal amount of time and then keep the stash empty when the stashed changes are no longer needed. It’s not fun to find something in your stash that is months old and you can not remember what it was.

For more information:

$ git help stash