Stashing Uncommitted Changes in Git
9 min read·Jan 1, 2025
In Git, stashing consists in storing the changes made to the working tree and the staging area into a temporary storage area called the stash, and resetting both areas to the state of the HEAD commit.
It allows developers to quickly switch branches or experiment with code without risking losing their current work.
For example, if a critical bug that needs immediate attention is discovered and you're in the middle of implementing a new feature, you can stash your changes, fix the bug, and then apply the stash to continue your work.
Keep in mind that the stash is not meant to be a long term solution and that the longer changes stay stashed, the more likely they are to be outdated and cause merge conflicts when applied.
Stashing uncommitted changes
To save your local changes as a new entry in the stash list, you can use the git stash command:
$ git stash [-u] [-m message]
Where:
-uis an optional flag used to also stash untracked files.-mis an optional flag used to write a short and meaningful message (similar to a commit message) that makes it easier to identify and apply each stash later.
Example
Let's consider the following repository with an unstaged file:
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: index.js
no changes added to commit (use "git add" and/or "git commit -a")
When stashing the index.js file:
$ git stash -m "refactor: WIP add server logging"
Saved working directory and index state On master: refactor: WIP add server logging
The repository then shows as clean:
$ git status
On branch master
nothing to commit, working tree clean
Listing stash entries
To get the list of stash entries, you can use the list subcommand:
$ git stash list
Example
In this example, the stash list contains only one entry from the master branch:
$ git stash list
stash@{0}: On master: refactor: WIP add server logging
Applying stash entries
To apply a stash to the working tree and staging area, you can use the the apply subcommand:
$ git stash apply [stash@{index}]
Where:
indexis the stash entry number obtained using thegit stash listcommand.
Notes:
By default, if the
stash@{index}expression is not specified, the command will apply the most recent stash entry.Applying a stash might sometimes result in a merge conflict, which will need to be resolved like any other conflict.
Example
This command will apply the stash index 0 on the master branch:
$ git stash apply stash@{0}
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: index.js
no changes added to commit (use "git add" and/or "git commit -a")
Removing stash entries
By default, stashed entries will remain in the list, even after applied, unless explicitly removed.
To remove a stash entry from the list, you can use the drop subcommand:
git stash drop [stash@{index}]
Alternatively, to apply and remove a stash entry at the same time, you can use the pop subcommand:
$ git stash pop [stash@{index}]
Which is equivalent to running git stash apply followed by git stash drop.
💡 Tip: It is considered good practice to remove stashes as soon as they're not anymore needed in order to keep the stash list clean and avoid confusion.
Example
Let's consider this stash:
$ git stash list
stash@{0}: On master: refactor: WIP add server logging
This command will pop the stash index 0 to the master branch, resulting in its automatic removal:
$ git stash pop stash@{0}
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: index.js
no changes added to commit (use "git add" and/or "git commit -a")
Dropped stash@{0} (593e2bf74fd1e76bd14ea02c7166097711267dc4)
Creating branches from stash entries
To create a new branch from a stash and directly apply its content to it, you can use the branch subcommand:
$ git stash branch <branch_name> [stash@{index}]
Note: This command will automatically check out the newly created branch and remove the specified entry from the stash list if the operation is successful.
Example
Let's consider this stash:
$ git stash list
stash@{0}: On master: refactor: WIP add server logging
This command will create a new feature branch named feature/server-logging from the stash index 0:
$ git stash branch feature/server-logging stash@{0}
Switched to a new branch 'feature/server-logging'
On branch feature/server-logging
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: index.js
no changes added to commit (use "git add" and/or "git commit -a")
Dropped stash@{0} (fad129ddb2641ee714d2710ade10509a20202813)
$ git branch
* feature/server-logging
master
Summary
Here's a summary of what you've learned in this lesson:
- The stash is a temporary storage area used to save the current state of the working tree and the staging area.
- The
git stashorgit stash pushcommand is used to temporarily store the state of the working tree and staging area. - The
git stash listcommand is used to output the list of stash entries. - The
git stash applycommand is used to apply a stash entry. - The
git stash dropcommand is used to remove an entry from the stash list. - The
git stash popcommand is used to apply and remove an entry from the stash list. - The
git stash branchcommand is used to create and checkout a new branch from a stash entry.
Enjoying the courses?
I've made these courses completely free so anyone can learn from them. If they've helped you and you'd like to actively support the work behind BackendBrewery, you can leave a tip:
Support BackendBrewery