A practical guide to using the git stash command – Opensource.com

Version control is an inseparable part of the daily lives of software developers. It’s hard to imagine any team developing software without using a version control tool. It’s equally hard to imagine any developer who hasn’t worked with (or at least heard of) Git. In the 2018 Stackoverflow developer survey, 87.2% of the 74,298 participants use Git for version control.

Linus Torvalds created git in 2005 to develop the Linux kernel. This article walks through the git stash command and explores some useful options for saving changes. It assumes that you have basic familiarity with Git concepts and a good understanding of the worktree, staging area, and associated commands.

Why is the git stash important?

The first thing to understand is why it’s important to save changes to Git. Let’s assume for a moment that Git doesn’t have a command to save changes. Suppose you are working in a repository with two branches, A and B. Branches A and B have diverged from each other for quite some time and have different heads. While working on some files in branch A, your team asks you to fix a bug in branch B. Quickly save changes to A and try to check out branch B with git checkout B. Git immediately aborts the operation and throws the error: “Local changes to the following files would be overwritten by checking out… Please confirm your changes or save them before changing branches.”

There are few ways to enable branch switching in this case:

  • create a commit at that point in branch A, commit and submit your changes to fix the error in B, then check A again and run git reset HEAD^ to retrieve your changes
  • .

  • Manually keep changes to files not tracked by Git.

The second method is a bad idea. The first method, while it seems conventional, is less flexible because unfinished saved changes are treated as a checkpoint rather than a patch that is still a work in progress. This is exactly the kind of scenario git stoil is designed for.

Git stash saves uncommitted changes locally, allowing you to make changes, change branches, and perform other Git operations. You can then reapply the hidden changes when you need them. A stash has a local scope and is not pushed to the remote using git push.

How to use git stash

This is the sequence to follow when using

git stash: Save changes to branch A. Run git

  1. stash
  2. .

  3. Check out
  4. branch B.

  5. Fix the error in
  6. branch B.

  7. Confirm and (optionally) push to remote
  8. .

  9. Check out the A
  10. Run git stash pop branch to retrieve your saved changes.

Git stash stores changes made in the working directory locally (within your project’s .git directory; /.git/refs/stash, to be precise) and allows you to retrieve changes when you need them. It’s useful when you need to switch between contexts. It allows you to save the changes you may need at a later stage and is the fastest way to clean up your working directory while keeping the changes intact.

How to create a


The simplest command to save changes is git stash: $ git

stash Saved working directory and WIP index status in master; d7435644 Feat: Configure the graphql endpoint

By default, git stash stores (or “hides”) uncommitted changes (preconfigured and non-preconfigured files) and ignores untracked and ignored files. There’s usually no need to save untracked and ignored files, but sometimes they can interfere with other things you want to do in your codebase.

You can use additional options to allow git stash

to take care of

untracked and ignored files: git stash -u or git stash -include-untracked stash untracked files. git stash –

  • a or git stash –
  • all

  • hidden files not tracked and files ignored.

To save specific files, you can use the

git stash -p or git stash -patch: $ git stash -patch diff -git a/.gitignore b/.gitignore index 32174593..8d81be6e 100644 – a/.gitignore +++ b/.gitignore @@ -3.6 +3.7 @@ # dependencies node_modules/ /.pnp +f,fmfm .pnp.js # testing (1/1) Save this chunk [y,n,q,a,d,e,?]?


your stash

You can view your stash with the git stash list command. Caches are saved in a LIFO (last in, first out) approach

: $ List of git caches stash@{0}: WIP on master: d7435644 Feat: Configure graphql endpoint

By default, caches are marked as WIP at the top of the branch and confirm that you created the stash from which it was made. However, this limited amount of information is not useful when you have multiple storages, as it becomes difficult to individually remember or verify its contents. To add a description to the stash, you can use the command

git stash save <description>: $ git stash save “delete semicolon from schema” Saved working directory and index status In master: remove semicolon from schema $ git stash list stash@{0}: In master: remove semicolons from schema stash@{1}: Work in progress in master: d7435644 Feat: Configure the graphql endpoint

Hidden change recovery

You can reapply hidden changes using the git stash apply and git stash pop commands. Both commands reapply the changes saved in the last stash (that is, stash@{0}). A stash reapplies the changes, while pop removes the changes from the stash and reapplies them to the working copy. Bursting is preferred if you do not need hidden changes to be reapplied more than once.

You can choose which stash you want to pop or apply by passing the identifier as the last argument:

$ git stash pop stash@{1}


$ git stash apply stash@{1}

Cleaning the stash

It is a good practice to remove stash that is no longer needed. You must do this manually with the following commands:

Git stash Clear empties the

  • hiding list by deleting all hiding places. Git
  • stash

  • drop <stash_id> removes a particular stash from the stash list.


for stash differences The git stash show command

<stash_id> allows you to see the diff of a stash: $ git stash show

stash@{1} console/console-init/ui/.graphqlrc.yml | 4 +- console/console-init/ui/generated-frontend.ts | 742 ++++++++++- console/console-init/ui/package.json | 2 +-

For a more detailed difference, pass the -patch or -p:

$ git stash show stash@{0} -patch diff -git a/console/console-init/ui/package.json b/console/console-init/ui/package.json index 755912b97.. 5b5af1bd6 100644 – a/console/console-init/ui/package.json +++ b/console/console-init/ui/package.json @@ -1.5 +1.5 @@ { – “name”: “my-usepatternfly”, + “name”: “my-usepatternfly-2”, “version”: “0.1.0”, “private”: true, “proxy”: “http://localhost:4000” diff -git a/console/console-init/ui/src/AppNavHeader.tsx b/console/console-init/ui/src/AppNavHeader.tsx index a4764d2f3.. da72b7e2b 100644 – a/console/console-init/ui/src/AppNavHeader.tsx +++ b/console/console-init/ui/src/ AppNavHeader.tsx @@ -9.8 +9.8 @@ import { css } from “@patternfly/react-styles”; IAppNavHeaderProps interface extend PageHeaderProps { – toolbar?: React.ReactNode; – avatar?: React.ReactNode; + toolbar?: React.ReactNode; + avatar?: React.ReactNode; } export class AppNavHeader extend React.Component<IAppNavHeaderProps>{ render()Check out to a



You might encounter a situation where changes to a branch and its stash diverge, causing a conflict when you try to reapply the stash. A clean solution for this is to use the git stash branch <new_branch_name stash_id> command, which creates a new branch based on the commit from which the stash was created and displays the hidden changes in it: $ git stash

branch test_2 stash@{0} Changed to a new branch ‘test_2’ In the branch test_2 Unorganized changes to commit: (use “Git add <file>…” to update what will be committed) (use “Git Restore <file>…” To discard changes to the working directory) modified: .graphqlrc.yml modified: generated-frontend.ts modified: package.json No changes were added to commit (use “git add” and/or “git commit -a”) Removed stash@{0} (fe4bf8f79175b8fbd3df3c4558249834ecb75cd1)

Storage without disturbing

the hiding place reflog

On rare occasions, you may need to create a stash while keeping the reflog intact. These cases can arise when you need a script to hide as a deployment detail. This is accomplished by the git stash create command; Creates a stash entry and returns its object name without pushing it to the cache

reflog: $ git stash create “sample stash” 63a711cd3c7f8047662007490723e26ae9d4acf9

Sometimes, you may decide to push the stash entry created through git stash create al stash reflog: $ git

stash store -m “sample stash testing..” “63a711cd3c7f8047662007490723e26ae9d4acf9” $ git stash list stash @{0}: sample stash testing..


I hope you found this article useful and learned something new. If I missed any useful options for using stash, let me know in the comments.

Contact US