Image of A Guide to Git Stash: Save Changes for Later

ADVERTISEMENT

Table of Contents

Introduction

When using Git, sometimes you’ll find yourself wanting to shift away from what you're currently working on, without losing uncommitted changes you've made in your working directory.

Something more urgent or interesting may have come up, but you’re in the middle of a code change. Luckily, you can easily stash your uncommitted changes and come back to it later.

In this guide, you’ll learn how to use git stash and associated subcommands, plus have your common questions answered.

What is Git Stash?

Git stash is a powerful Git command that is useful when you need to stop what you’re working on and switch to something else. It allows you to stow away the changes that you are have currently made, for later.

The result is a clean working directory in which you can make new changes, fix bugs, develop a new feature, or something else. When you're ready, you can reapply your stashed changes to the working directory and commit as desired.

Why Do We Use Git Stash?

Git Stash is all about convenience. The git stash command makes it very easy to be flexible with your work. It is commonly used in the following situations:

  • Adding or changing something after the most recent commit that differs from your working directory changes
  • Having identified a new feature or bug that needs immediate work
  • Having experimental code changes in the working directory but not being ready to commit them yet
  • Merging a local or remote branch without conflicting your working directory changes

These are just a few of the times you'll benefit from Git stash.

How Git Stash Works?

Git is designed to be accessible and easy to use, but there’s a lot going on behind the scenes. When using the git stash command, Git will queue your working directory changes in a last-in-first-out (LIFO) structure. If you stash multiple items, this will result in a stack structure to hold these stash entries.

Git stores your stash entries in the hidden .git directory at the path .git/refs/stash, meaning all stashes are local. When you use git stash to save changes, these are kept in your local repository and will not be pushed to a remote repository or impact your colleague’s work.

Local stash only means there is no remote backup of stashes. If the local copy of your repo is damaged or lost, you will lose any stashed code changes.

Stashing Notation

When you want to access a Git stash entry, it helps to understand the following notation:

stash@{n}

Where n is the stash entry number (or index number), starting at 0.

For example, if you’ve stashed 3 times, your stashes will be:

stash@{0}
stash@{1}
stash@{2}

How Do I Use Git Stash?

In many cases, when using git stash you will be stashing your current changes and then retrieving those stashed changes once you’re finished with your side issue. But sometimes you will need to manage multiple stash entries, drop an unneeded stash entry, compare differences between stashes, or checkout your stashes to a new branch.

You can do all of this if you learn the following git stash subcommands.

1. Stash Current Changes

Before stashing current work, it’s a good idea to use git status to check on the state of your working directory:

$ git status
On main branch
Changes to be committed:

	new file: index.html

Changes not staged for commit:

        modified: homepage.html 

Next use git stash to save these changes:

$ git stash
	Saved working directory and index state WIP on main: editing homepage

Now you have a clean working directory and can fix your bugs, create new commits, or perform any other Git actions. When ready, you will be able to retrieve your stashed changes.

2. Manage Your Stashes

You can stash multiple times without issue. Maybe you want to work on a series of code changes, but aren’t ready to commit any of them, then you may stash each of these changes separately. This can help keep your work neat and isolated.

If you want to view all of your current stashes, you can use the command git stash list. Stashes are automatically saved as a "WIP" on top of the branch and commit you created the stash from. That’s why it’s good practice to include a descriptive message of the stash by using git stash save "enter message here".

$ git stash list 

stash@{0}: WIP on main 1a2b3c4d editing homepage
stash@{1}: WIP on main 1a2b3c4d editing homepage
stash@{2}: WIP on main 1a2b3c4d editing homepage

See how none of these stashes are noted with any message. Once you have stashed a few changes, it can be confusing to determine which stash is which. Did stash 0 have that bug fix or was that stash 1?

Here’s an example of adding a descriptive message when stashing:

$ git stash save "adding images to homepage"

	Saved working directory and index state On main: adding images to homepage
	HEAD is now at 1a2b3c4d editing homepage

If you add messages when stashing, it will be significantly easier to read when you list your stashes:

$ git stash list
stash@{0}: On main: adding images to homepage
stash@{1}: On main: adding links to homepage
stash@{2}: On main: adding headers to homepage

3. Delete a Stash Entry

If you decide you don’t need a specific stash entry any longer, you can delete it with a single command, git stash drop. Check this command out below:

$ git stash drop stash@{1}
Dropped stash@{1} (5fb8d0720a2563f65c4843ff98fca240875)

If you want to clear the whole stash, you can drop all stash entries using git stash clear:

$ git stash clear

4. Check Stash Differences

If you don’t remember the content of changes from a stash, you can get a summary using git stash show. This will display the differences between your stash and the last commit before the stash was created. The short summary will look like this:

$ git stash show 
index.html | 1 +
homepage.html | 3 +++
2 files changed, 4 insertions (+)

If you want the long-form summary (and know how to read it), use git stash show -p.

5. Checkout New Branch

You stashed changes and worked on something else. Now your working copy and most recent commit have changed. When you got to re-apply the stash, you may experience some conflicts or issues. To avoid this possibility, you can create a new branch using git stash branch.

The general format of this command should be git stash <new-branch-name> stash@{n} where you sub in the "new-branch-name" with your branch name and the stash with your stash identifier. Check out this example below:

$ git stash branch add-homepage stash@{0}
Switched to a new branch `add-homepage`
On branch add-homepage
Changes to be committed:

	new file: index.html

Changes not staged for commit:

        modified: homepage.html 

Dropped refs/stash@{0} (967e2dcbf01b57f88225504d24b75ac)

6. Retrieve Stashed Changes

If you’re ready to return to a stashed code change, so you can complete your work, you will be using git stash pop. When you ‘pop’ your stash you are removing that change from your stash. It will be applied to your working copy. Look at git stash pop in action:

$ git stash pop
On branch main
Changes to be committed:

	new file: index.html

Changes not staged for commit:

        modified: homepage.html 

Dropped refs/stash@{0} (967e2dcbf01b57f88225504d24b75ac)

Alternatively, you can re-apply the changes to your working copy AND keep the changes in your stash. You can then apply these stashed changes across multiple branches or keep them in an early state. For this you would use the command git stash apply:

$ git stash apply
On branch main
Changes to be committed:

	new file: index.html

Changes not staged for commit:

        modified: homepage.html 

Can you Stash Untracked Files or Ignored Files?

By default, Git will not stash any untracked or ignored files.

Untracked files are those that are currently not tracked by Git (git add has never been run for them). You can check if a file is tracked by using git status. Ignored files are files that you have explicitly asked Git to completely ignore.

While Git will not stash these types of files by default, you can add some command flags to get around this. Check out the following subcommands for stashing untracked files:

$ git stash -u
$ git stash --include-untracked
$ git stash --only-untracked

The following flags can be used to stash ignored files:

$ git stash -all

Summary

If you weren’t familiar with stashing in Git before, now you have the basics covered. This guide covered how and why to use git stash. You learned how it works behind the scenes, the general workflow for stashing changes, and how to use the various subcommands and flags.

Git stash is a great command to add to your Git repertoire. Mastering git stash will provide you with extra flexibility in how you tackle your development scenarios. When you start working on code changes, don’t be afraid that you have to finish them before you can start something else. With git stash you have the freedom to change gears on your project, whenever you need to, without losing any work.

Next Steps

If you're interested in learning more about how Git works under the hood, check out our Baby Git Guidebook for Developers, which dives into Git's code in an accessible way. We wrote it for curious developers to learn how Git works at the code level. To do this we documented the first version of Git's code and discuss it in detail.

We hope you enjoyed this post! Feel free to shoot me an email at jacob@initialcommit.io with any questions or comments.

References

  1. Git SCM Docs, git stash - https://git-scm.com/book/en/v2/Git-Tools-Stashing-and-Cleaning

Final Notes