Icon

Charles C

Become a git stash pro

January 26, 2021

git stash is a very useful feature in git allowing you to 'stash' away changes for later.

Key points for git stash:

  • Stashes are a last-in-first-out list. You can push and pop to it
  • Stashes have an index (the latest is 0), and optionally a message (like commits)
  • Stashing requires a commit. You can't stash if you haven't created a commit yet (for example - right after git init)

Stashing is useful in a few cases:

  • When you want to pull or rebase, and have a dirty working directory
  • When you want to move changes between HEADs
  • When you want to keep changes for later
  • And a few more

We will setup our playground using the following:

mkdir git-stash-example # Create directory
cd git-stash-example # Change working directory to created directory
touch a # Create an empty file called 'a'

git init # Create git repository
git add . # Track and add all files (only 'a')
git commit -m "First commit" # Create our first commit (required to stash)

Basic usage

If you have made changes in your git repository (which can be checked using git status), you are eligible to stash.

For example, by creating a new file (touch b), we see that our repository is 'dirty' (has uncommited changes) using git status:

On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	b

nothing added to commit but untracked files present (use "git add" to track)

If we want to save this change for later, we can simply add the files with git add . and stash them using git stash (which is equivalent to git stash push).

Now, we see that there are no longer changes with git status. We can see that our stash was saved by using git stash list:

[email protected]{0}: WIP on master: 77ddd8b First commit

The list format indicates the index (here, {0}), and by default will show which branch you were working on, with the parent commit you were working from.

If we bring back our changes, we can use git stash pop (which will 'pop' the latest added item from the stash list).

> git stash pop

On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	new file:   b

Dropped refs/[email protected]{0} (8ba424dbd42ab3bab4ae219f6bf2ae40ba577c42)

Here, we see Dropped refs/[email protected]{0}, indicating that after being poped, our stash was dropped (deleted).

Let's restash it, with a message using git stash -m "Add b file". Now our git stash list will show the message:

[email protected]{0}: On master: Add b file

Advancing

You can drop (delete) stashes manually, using git stash drop <stash>. For example, we can drop our 0 stash using git stash drop 0.

You can clear all stashes using git stash clear (but I would discourage using this command, as stashes are very useful!).

When stashing, you can also use the -a option to avoid having to git add . before stashing: git stash -a

To view the contents of a stash, you can use git stash show <stash>. This will show the diff of the stash without applying.

To pop without dropping a stash, use git stash apply, which applies it like pop without dropping.

Auto stash

When rebasing, git offers the --autostash flag which will:

  • Stash your changes
  • Rebase
  • Unstash (pop) your changes

This can also be set to always happen using git config rebase.autoStash true.

You can read more about autostashing from this excellent article.

Patch

Using the -p flag when stashing allows you to interactively select hunks ("chunks" of changes) to be stashed or left dirty.

This is useful if you want to only stash parts of your changes. For more usage of interactive mode (it is the same mode from git add -i), you can read more from the documentation.

Cheat sheet

  • git stash: Stashes all changes (use -a to add files too)
  • git stash -p: Interactively select hunks to stash
  • git stash list: Lists all stashes, shows index and message
  • git stash -m "message here": Same as git stash, attaches a message to be shown in the stash list
  • git stash pop: 'Pops' (applies) the latest stash (the one with index 0) and drops it
  • git stash pop <index>: Pops a specific stash
  • git stash show <index>: View diff of a specific stash
  • git stash drop <index>: Drops (deletes) a specific stash
  • git stash clear: Drop all stashes
  • git stash apply [index]: Apply a stash without dropping it (same as pop)
  • git rebase --autostash: Automatically stash before rebasing, and unstash after

Conclusion

git stash is a very useful feature of git for development, and allows you to store half-finish features or local changes you don't wish to commit. It can also be used to easily move changes across branches or commits in a repository.

You can read more about it from the git documentation.

About me

I am Charles C, I work with JavaScript/TypeScript (Node, React), Flutter, Go, and many other technologies.

Follow me on Twitter!