A crash-course in git stashing tools

Have you ever found yourself working on your git project, having some unfinished feature on the way when suddenly someone asks you fix something on development branch or quickly push a hotfix to master. You face a choice. In order to checkout to other branch you either drop all your uncommited changes or you create a commit that doesn’t reflect a finished piece of work. Both are subpar in the least as you don’t want to lose your code and (as previously discussed in this post) you want your commit history to be nice and clean. What to do?

Git stash to the rescue!

Basic use of git stash is as follows.

//dirty directory. You need to check out somewhere
$ git add .
//no unstaged changes
$ git stash
$ git checkout some-branch
//you do all the work and are free to return to your WIP
$ git checkout original-branch
$ git stash pop
//dirty directory with the changes you made previously

Briefly speaking, git stash allows you to save all the changes you have uncommited in your local repo and retrieve them at a later time. I suits the problem I stated in the introduction perfectly. But come on, this is git. It has to be more powerful than that. And it is :).

Stashing your work

Actually git stash is just a handy shortcut to the real command that gets executed when you type it. To save the state of your current uncommited changes you need to execute

$ git stash save

Additionally you can name your stashes using

$ git stash save "Begin about-frag"

Naming stashes can be quite useful if you happen to be quickly testing out different approaches to a problem and want to save some of the attemps on the stash stack for later. Stash stack.. What the heck is that?

Understanding the stash stack

To see what I’m talking about execute this command. Assuming you have already made some stashes, you will see something along the lines

$ git stash list
stash@{0}: WIP on about-frag: 1b3ddea Maybe better approach
stash@{1}: WIP on about-frag: 9f55c34 Try lib1
stash@{2}: WIP on about-frag: 7bfd291 Begin about-frag

As you can see you have several stashes stacked on top of each other. Executing git stash apply defaults to the one on the top – in this case stash@{0} – and applies the changes to your clean repo. In order to specify another snapshot use one of the following commands:

$ git stash apply stash@{2}
$ git stash apply stash^{/Begin abo}

They respectively apply the stash indexed with 2 and the youngest one starting with string “Begin abo” which in this case is the same stash.

If you want to get rid of a certain snapshot after applying it you can use git stash drop as follows:

$ git stash drop
$ git stash drop stash@{2}
$ git stash drop stash^{/Begin abo}

The most common operation is applying the latest stash and removing it from the stack which has its own handy alias:

$ git stash pop

To remove all snapshots use:

$ git stash clear

Mastering git stash for better commit history

Another useful thing you can for example to make more structured commits is using partial stashing. Its basic principle is the idea of changes being processed in hunks. Basically, every “block of code” you change is represented by one hunk. To see the list of hunks in a snapshot use

$ git stash show
$ git stash show "name-of-stash"

To interactively choose which changes to put in a new stash use

$ git stash -p

Then for every hunk you can use what you want to do. Press ? to see an explanation of what to do next.

Bits and pieces

If at any point you realise that the contents of a given stash are worthy of their own branch you can easily create a branch and pop a certain snapshot with the following command:

$ git stash branch new-branch-name stash@{3}

There are also several cool options you can use if you want to specify the more advanced behaviour of certain stashing commands:

 

--keep-index

[default for git stash -p] adds the dirty repo state but leaves the indexed changes intact

 

--no-keep-index

[default for git stash save] adds the dirty repo including the staging

 

--include-untracked

adds the untracked files as well – results in a really clean working directory

 

As you can see git is a really powerful tool and to fully leverage its power it’s crucial to try and learn as much as you can. If you are interested in that I advice you check out my other posts about git. Until next time, stay curious.

Leave a comment

Your email address will not be published. Required fields are marked *