At some point you may need to stash your changes in a dirty working directory. For example when you did not commit your local changes yet but you want to pull in changes from a remote repository. Or you quickly want to checkout a different branch without the need of committing your progress.
For those situations, stashing is the recommended way to do so. In this post I will give you a brief overview of what stashing in git is and I will demonstrate the basic workflow. To fully understand the given examples, a fundamental knowledge about git is required.
Stashing?
Stashing enables you to save your local changes away and resets your working directory to the HEAD
state. Stashed
changes can be re-applied whenever you need them. It is even possible to use stashes multiple times.
Create
Given you made changes (files have to be tracked, but it does not matter if staged for commit or not) in a git directory which contains at least one commit:
~/git-stashing (master*) $ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: bar.txt
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.txt
To create a stash use git stash
(or the equivalent git stash push
). This will store your changes away and your
working directory is clean again:
~/git-stashing (master*) $ git stash
Saved working directory and index state WIP on master: 377r7fd Initial commit
~/git-stashing (master) $ git status
On branch master
nothing to commit, working tree clean
It is also possible to add a description to a stash, which makes identification easier. You have to use the longer
version git stash push
and add -m <message>
:
~/git-stashing (master*) $ git stash push -m "Stash with message"
Saved working directory and index state On master: Stash with message
List
git stash list
displays a list of all your stashes:
stash@{0}: On master: Stash with message
Show
Inspect the latest stash using git stash show
:
~/git-stashing (master) $ git stash show
bar.txt | 0
foo.txt | 1 +
2 files changed, 1 insertion(+)
If you have multiple stashes, provide an index to inspect a specific one:
~/git-stashing (master*) $ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: baz.txt
~/git-stashing (master*) $ git stash
Saved working directory and index state WIP on master: 377r7fd Initial commit
~/git-stashing (master) $ git stash list
stash@{0}: WIP on master: 377r7fd Initial commit
stash@{1}: On master: Stash with message
~/git-stashing (master) $ git stash show 0
baz.txt | 0
1 file changed, 0 insertions(+), 0 deletions(-)
~/git-stashing (master) $ git stash show 1
bar.txt | 0
foo.txt | 1 +
2 files changed, 1 insertion(+)
Pop
By using git stash pop
the latest stash will be removed from the stash list and applied to your working directory
(provide an index to pop a specific stash):
~/git-stashing (master) $ git stash list
stash@{0}: WIP on master: 377r7fd Initial commit
stash@{1}: On master: Stash with message
~/git-stashing (master) $ git stash pop
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: baz.txt
Dropped refs/stash@{0} (24998f6d9e1729ecfc06b3a4a053f1d8rdd2b240)
~/git-stashing (master*) $ git stash list
stash@{0}: On master: Stash with message
Apply
git stash apply
adds the latest stash to your working directory but keeps the stash remaining in the list for further
usage (provide an index to apply a specific stash):
~/git-stashing (master*) $ git stash list
stash@{0}: On master: Stash with message
~/git-stashing (master*) $ git stash apply
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: bar.txt
new file: baz.txt
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.txt
Dropped refs/stash@{0} (3b0d45285ea3a1d0ebc4f6224db8a6143bade95e)
~/git-stashing (master*) $ git stash list
stash@{0}: On master: Stash with message
Drop
To remove the latest stash from the list without applying it, use git stash drop
(provide an index to drop a specific
stash):
~/git-stashing (master*) $ git stash list
stash@{0}: On master: Stash with message
~/git-stashing (master*) $ git stash drop
Dropped refs/stash@{0} (f320e2631b414fe9230c1d84d7f09339ac8918fd)
Oh My Zsh aliases
A workflow tip from my side to close up this post - use Oh My Zsh! It comes with a bunch of useful and convenient aliases for git, including shortcuts for stashing:
gsta='git stash save'
gstaa='git stash apply'
gstall='git stash --all'
gstc='git stash clear'
gstd='git stash drop'
gstl='git stash list'
gstp='git stash pop'
gsts='git stash show --text'
For further information about git stashing, have a look at the official documentation at https://git-scm.com/docs/git-stash