Recently I’ve been using git stash a lot, and decided it was time to have a proper look at GIT-STASH(1) to have a proper understanding of what this command does and how I can get the most out of it.

Before starting though let’s make something clear, you should not use git stash. Or better you should not put yourself in a situation where you need to stash unfinished work and change branch to work on something else.

We all know how counter productive context switching is. So it’s way better to work in a linear way, branching out when starting a new feature, refactor or fix, working our way through it, finishing it, and merging it back. Having many WIPs hanging around is quite dangerous. Plus once something has been started we should try to finish it as soon as possible, in order to ship it and collect useful feedback.

Given that we all agree that we should avoid stashing as a best practice, there are cases in which stash is the best command for the job. In my case it has mostly been freezing what I was doing and investigating what caused the automated tests to fail on CI.

So, let’s look at what git stash is and does. From GIT-STASH(1):

Use git stash when 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 HEAD commit.

So stashing kinda like making a commit, only that instead adding the commit to the branch history, all the changes go into the stash, leaving HEAD as we found it.

The modifications stashed away by this command can be listed with git stash list, inspected with git stash show, and restored (potentially on top of a different commit) with
git stash apply. Calling git stash without any arguments is equivalent to git stash save. A stash is by default listed as “WIP on branchname …”, but you can give a more
descriptive message on the command line when you create one.

The basic workflow for stashing is using git stash save, or just git stash, to stash away the changes, going to do other things on the codebase then coming back and using git stash apply to restore the modifications and carry on with what we were doing.

If we use gis stash save "A meaningful message" to stash our edits with a proper message we can avoid using git stash show to inspect them to remember what they were about.

If you used stash more than once in the lifetime of your local repository, then by using git stash list you can see all the stashed states.

If you have to recur to stashing a number of time the stashed states list can grow out of control. In this case you can use git stash drop <stash> to remove a single state from the list, or be more brutal and use git stash clear to get rid of everything and leave the past behind.

Another option to keep your stash list under control is using git stash pop <stash>, which the same way apply does, but also drops the restored state from the list.

A usual with git we could go on for ages enumerating the possible options, or all the different combo of commands that can be made, but let’s wrap it up with a couple of tips:

  • When using stash and pop if you omit the <stash> id the most recend state will be restored. Which makes sense: the stash list is a LIFO, and we use pop on it.
  • You can use git stash apply --patch to open an interactive section and stash only certain hunks.
  • You can use git stash apply --include-untracked to stash the untracked files, avoiding carrying them with you.
  • The list command takes the same options of git log, have fun!
  • Using git stash branck <branchname> [<stash>] you can create a new branch and restore the stashed changes in one go.

Food for thought

  • Look into the other commands and options.
  • What is the difference in the way commits and stashed states are stored?