When stashing away work, we can easily have more than one state of work stashed away at a time. However, the default names for the stashed away changes aren't always helpful. In this example, we'll see how we can save stashes and name them so that it is easy to identify them again when listing the content of the stash. We'll also learn how to apply a stash without deleting it from the stash list.
We'll use the same repository as in the previous example, continuing from the state we left it in:
$ cd cookbook-tips-tricks $ git status On branch master Your branch is ahead of 'origin/master' by 1 commit. (use "git push" to publish your local commits) Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: foo $ git stash list stash@{0}: WIP on master: 4447f69 Update foo
To save the current state to a stash with a description we can remember a later point in time, use the following command:
$ git stash save 'Updates to foo' Saved working directory and index state On master: Updates to foo HEAD is now at 4447f69 Update foo
Our stash list now looks like the following:
$ git stash list stash@{0}: On master: Updates to foo stash@{1}: WIP on master: 2302181 Update foo
We can change bar
and create a new stash:
echo "Another change" >> bar $ git stash save 'Made another change to bar' Saved working directory and index state On master: Made another change to bar HEAD is now at 2302181 Update foo $ git stash list stash@{0}: On master: Made another change to bar stash@{1}: On master: Updates to foo stash@{2}: WIP on master: 2302181 Update foo
We can apply the stashes back to the working tree (and staging area with the --index option
) without deleting them from the stash list:
$ git stash apply 'stash@{1}' On branch master Your branch is ahead of 'origin/master' by 1 commit. (use "git push" to publish your local commits) Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: foo no changes added to commit (use "git add" and/or "git commit -a") $ git stash apply --quiet 'stash@{0}' $ git stash list stash@{0}: On master: Made another change to bar stash@{1}: On master: Updates to foo stash@{2}: WIP on master: 2302181 Update foo
The stashes are still in the stash list, and they can be applied in any order and referred to with the stash@{stash-no}
syntax. The --quiet
option suppresses the status output after the stashes have been applied.
For the stashes applied with git stash apply
, the stash needs to be deleted with git stash drop
:
$ git stash drop 'stash@{1}' Dropped stash@{1} (e634b347d04c13fc0a0d155a3c5893a1d3841fcd) $ git stash list stash@{0}: On master: Made another change to bar stash@{1}: WIP on master: 1676cdb Update foo
Keeping the stashes in the stash list by using stash apply
and explicitly deleting them with git stash drop
has some advantage over just using stash pop
. When using the pop
option, the stashes in the list are automatically deleted if they can be successfully applied, but if it fails and triggers the conflict resolution mode, the stash applied is not dropped from the list and continues to exist on the stash stack. This might later lead to accidentally using the wrong stash because it was thought to be gone. By consistently using git stash apply
and git stash drop
, you can avoid this scenario when done.
The git stash
command can also be used to apply debug information to an application. Let's pretend you have been bug hunting and have added a lot of debug statements to your code in order to track down the bug. Instead of deleting all those debug statements, you can save them as a Git stash:
git stash save "Debug info stash"
Then, if you later need debug statements, you can just apply the stash and you are ready to debug.