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:

  • -u is an optional flag used to also stash untracked files.
  • -m is 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:

  • index is the stash entry number obtained using the git stash list command.

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 stash or git stash push command is used to temporarily store the state of the working tree and staging area.
  • The git stash list command is used to output the list of stash entries.
  • The git stash apply command is used to apply a stash entry.
  • The git stash drop command is used to remove an entry from the stash list.
  • The git stash pop command is used to apply and remove an entry from the stash list.
  • The git stash branch command 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
Stashing Uncommitted Changes in Git | Backend Brewery