What is git stash

Suppose you are working on a feature, the work is still in progress and you are not ready to commit yet. However, you need to switch to another branch to fix a bug or make some other urgent change. You could commit your unfinished work and amend the commit later, but you don't want to do that. You want to keep your commit history clean. What do you do?

You can use git stash instead. It will save your current working directory and index state in a stack of unfinished changes that you can reapply later, and reset your current state to the point where it was before you started working on this feature, the point of your last commit.

How to use it

$ git status
On branch master
Your branch is up to date with 'origin/master'.

Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git restore ..." to discard changes in working directory)
        modified: rebase-flow.md

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

The state is currently dirty, it has uncommitted changes. So now we run git stash and check the status again.

$ git stash
Saved working directory and index state WIP on master: 8f39344 added
a document explaining the rebase workflow
$ git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

The state is now clean, it has no uncommitted changes. We can now switch to another branch and make the urgent change if we want.

When you run git stash your current uncommitted changes are placed on a stack of unfinished changes. You can run git stash list to see the list of stashed changes. You can run git stash multiple times and each time a new entry will be added to the stack.

$ git stash list
stash@{0}: WIP on master: 8f39344 added a document ...
stash@{1}: WIP on master: 8f39344 added a document ...
stash@{2}: WIP on master: 8f39344 added a document ...

Once you are done with the urgent work and want to resume the work you were doing before you can run git stash apply to apply the topmost stash in the stack. If you want to apply a stash that is not the topmost one you can specify it by its index, for example git stash apply stash@{2}.

$ git stash apply
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
(use "git restore --staged ..." to unstage)
    new file: new-change.md

And things are again in the state they were before you ran git stash. You can now continue working on your feature and commit the changes when you are ready.

But even though you applied the stash, all the entries are still in the stack. To remove the entries from the stack you can run git stash drop to remove the topmost entry, or git stash drop <index> to remove a specific entry. Alternatively, you could run git stash pop instead of git stash apply. That will apply the topmost stash in the stack and also remove it.

Things to take into consideration

git stash will only save the changes that are already tracked by git. If you have new files that are not tracked by git, they will not be saved. You can run git stash -u to save untracked files as well, or simply stage them before stashing your changes. However if you have files that are ignored by git, they will not be saved. You can run git stash -a to save ignored files as well.

Finally, if you want to clear the entire stack of stashed changes and discard all of them you can run git stash clear.