Photo by NeONBRAND
Use case: You want to switch to a different branch on the same project (say from
staging), but you have uncommitted changes and git insists you commit before switching branches.
# from feature branch git checkout staging # error: Your local changes to the following files would be overwritten by checkout: # ansible-django/roles/web/tasks/setup.yml # Please, commit your changes or stash them before you can switch branches. # Aborting
git stash is really straightforward for most cases. It involves
git stash to “stash away” all your uncommitted changes in your current branch, and
git stash pop to restore those changes when you’re back in the branch where you want to apply those changes.
To stash your uncommitted changes:
# stash uncommitted changes before switching to work on another branch git stash git checkout staging
When you’re done working on the other branch, restore your uncommitted changes:
# restore previously stashed changes git checkout feature-branch git stash pop
Another neat fact about
git stash is that it is apparently maintained across the all branches in your git repository. What that means is if you do
git stash in feature-xyz branch, you can run
git stash pop in master branch, for example. This can be useful if you’ve accidentally written code on a wrong branch.
Git stash is not always the best solution
There are times when it’s not wise to use
git stash to keep your uncommitted changes before switching branches. I found that when I’m unsure how long I’m going to be working on another branch, it’s better to not use
The reason is simple: you might forget that you’d done work there. This happened to me a few times, and when I finally remembered that I’d done work and stashed it previously, it’s already too late. I’d have gone ahead and re-did the work.
So in situations where you’re unsure how much time you will be spending working on a different branch in the same repository, it’s probably best to do what I’ve come to call (to myself) a “reluctant commit”.
A reluctant commit (I use the shorthand “RC” in commit messages to indicate this) is my made-up alternative of
git stash. (In fact I used it way before discovering
git stash.) The steps are:
- Commit the changes on the branch you’re about to leave behind
- Indicate in the commit message that it is a reluctant commit
- Checkout to another branch to work on it
- When back on the branch you left behind, if you merged new commits to master, run
git rebase masterto put your RC on top of the latest commit from master branch and continue working
- When done, squash commits
The benefit of this RC approach is that you don’t have to rely on your own memory to remember that you had already begun work on the branch - it’s already committed. Run
git log to check what you’d already done, and carry on from there.
# do a reluctant commit before switching to another branch git add . git commit -m "RC: in middle of adding product API" git checkout feature-branch-2
When done working on this branch, I’d usually clean up the commits by squashing them using
git rebase -i HEAD~n, where n=number of commits to squash into 1. (For more details on rebase, see squash git commits guide.) This way, the reluctant commit is squashed into the final, single commit.
That’s it about reluctant commits.
Please note that I’m merely covering the main use case of
git stash in this post, and deliberately left out the intricate and powerful peripheral options. For example,
git stash pop is actually restoring the changes and deleting the stash in the same command, which can be separated - like how
git pull is the combination of
git fetch and
Read more directly from the makers via the docs.
Other git-related short tutorials: