Stop Stashing

Published on June 14, 2020

I know the feeling, you are working on one branch, you need to fix something else in another branch and...

error: Your local changes to the following files would be overwritten by checkout:
Please commit your changes or stash them before you switch branches.

I used to just run git stash. It works, it removes your changes from the current branch and lets you move to the new branch and work on a different issue.

When you are done, you just have to come back to that branch and restore your changes with git stash apply or git stash pop.

Easy, right?

But you have to remember that you had your changes in the stash. Sometimes it can take days between a stash and trying to apply it. And you might have done other stashes in the way, so now it is not at the top, you need to find which one it was that you wanted.

What was the other alternative? Oh! right... commit. But stash is simpler. One command and you are done.

If only I could create a commit with just a single command...

Let me introduce you to git wip:

wip = !"git add . && git commit -m \"WIP $(date +'%F %R')\""
undo = "reset head^"

These are just two git aliases defined in my configuration file. With these, my workflow looks like this:

I'm working on feature A but need to fix something on feature B:

$ git wip
$ git checkout feature-b
Switched to branch 'feature-b'

$ # fixes

$ git checkout feature-a
Switched to branch 'feature-a'
$ git undo

$ # keep working

It is now much easier to recognize I have changes pending in my branch, I just run git log and there they are:

487e1f7 Ignacio Cata.. WIP 2020-06-14 17:14 (feature-a)
1dc8344 Ignacio Cata.. Add comments for articles (origin/master, master)

I can even rebase with the wip commit in there:

Want to get the most recent master:

git wip
git rebase master

If there is a problem, you just abort that rebase and everything is back to a safe state.

git rebase --abort

I can hear you thinking, what about taking changes from one branch to another?

That's what cherry-pick is for, isn't it?

$ git checkout -b new-feature-a
$ git log feature-a

487e1f7 Ignacio Cata.. WIP 2020-06-14 17:14 (feature-a)
1dc8344 Ignacio Cata.. Add comments for articles (origin/master, master)

$ git cherry-pick 487e1f7 # (hash copied from above)

On top of all these, because you committed your changes, they are now in the reflog for git so you can always recover them.

Another great use for these commits is as a checkpoint.

You have a working state but want to do some refactoring. Just add a wip commit. All the new changes are easy to spot and if something doesn't work out, you just revert.

Let me know what you think. Do you use stash? Have I missed something?