Let's say we are working on a feature branch called feature/human where we have to build a representation of humans. We are almost done with our development but not ready to commit yet as something is still missing.
At the same time, we need to do an urgent fix on a previously developed feature (about animals), for which we need to switch back to the main branch and start a new fix branch (fix/animal).
We might end up with carrying around incomplete changes that were made for a given purpose, on other branches that have nothing to do with it, causing confusion at the moment of the commit, as we will be forced to select from the changelist only the relevant files for the current scope. The more the changes, the more the confusion.
Here is when Git Stash comes to our aid by allowing us to freeze and save the state of our changes in the "stash" for a later retrieval, keeping the changelist clean and consistent on each involved branch.
Let's see the example in action. For simplicity, we are going to limit the number of changes made.
This is the initial state of the project on the main branch:
that is printing to the console:
Lion makes Meow
Cat makes Roar
Dog makes Foow
As you might have noticed, there are two bugs: the sounds of lion and cat should be inverted, and the dog's sound is not spelled correctly.
Let's imagine we did not notice the bugs yet and already started the new feature about humans.
This is the feature/human branch we are currently working on:
and here is the changelist:
We already made a bunch of changes but the development is incomplete as we still need to implement the sayHello
method.
However, someone made us notice the bugs on the animal package, and we need to fix them urgently (they are live in production!) before going ahead with humans.
We cannot operate on the current feature branch as it won't compile. What's more, the fix is not consistent with the scope of the branch and we don't want to create confusion by messing up the working tree.
Using Git Stash will solve our problems.
From the terminal, let's type the following command:
git stash save "human - TODO sayHello"
that will save our changes to the stash with a custom message, cleaning up the changelist so that we can switch branches without carrying around incomplete developments.
Now we can switch back to our main branch, start a new fix branch for animals, fix the bugs and merge it.
When finished, we can get back to the feature/human branch we were working on and type on terminal:
git stash list
that will print:
stash@{0}: On human: human - TODO sayHello
as you see, the stash area contains the changelist that we saved before and On human indicates we saved them from the feature/human branch.
to apply the changes again, we can use two alternative commands:
git stash pop
will retrieve the changes and remove them from the stash.
git stash apply
will retrieve the changes and keep the copy on the stash.
This second option is useful especially when we want to save specific "states" of the project before going ahead with other changes that will potentially break up things. It can be a lifesaver for delicate and complex developments as it allows to re-apply different versions of the changelist.
For example, let's say we want to try a different approach for the development to see if it works better. We might save the previous version of the changes, start the new approach and save the relative changelist as well on the stash.
Here is how our stash area might look like after that:
stash@{0}: On human: human - new approach
stash@{1}: On human: human - TODO sayHello
Let's imagine we showed both approaches to a senior developer for a review and we realise that the original approach actually works better than the new one. We can re-apply the first version state by typing:
git stash pop stash@{1}
if we also want to remove it from the stash list, otherwise:
git stash apply stash@{1}
if we want to keep a copy instead.
As you can see, the stash@{...}
identifies specific states, and we need to specify it only if we are not aiming at the most recent state change.
To conclude with the basics of git stash, another command is worth mentioning:
git stash drop
that is used to remove a state change from the list. As for the pop
and apply
operations, without specifying the stash@{...}
identifier it will remove the most recent changelist, otherwise we must specify it.
We came to the end of this brief explanation of a real world scenario where git stash can help you keeping your workflow cleaner, saving you from confusion and potential compiling errors as well.
As the title of this article states, use it and you won't regret.
Hope you enjoyed the article, feel free to leave a comment, your feedback is very welcome.
See you soon and keep stashing!
Top comments (0)