A blog about software development, written by Daniel Diekmeier. Archive.

Undo your last commit with git reset --soft "HEAD^" for a better™ stash workflow

January 4, 2023

At work, I switch between different Git branches all the time. Often, I’m working on a larger feature, but need to switch to some other branches for some quick fixes or because I’m reviewing someone elses code.

When I do that, I want to save my progress to the current branch.

I know, I know: I could use git stash for this, but I don’t really like it. It feels like throwing all your clothes on that chair in the corner of your room, hoping that you’ll find them again when you need them.

Instead, I got into the habit of committing all my changes to the current branch as a WIP commit.

git add . && git commit -m "WIP"

⚠️ Note: Don’t push this to the remote repository! It’s just a temporary commit to save your current progress.

This way, I can easily switch to another branch, do whatever needs to be done, and then bring back my changes:

git reset --soft "HEAD^"

By using --soft here, we bring back the changes to the working directory, and with "HEAD^", we only undo the last commit.


Update, February 18, 2023

Timo saw this post and created a Git Alias so he can easily WIP and un-WIP his changes:

wip = !"[[ $(git log -1 --pretty=%B) == \"WIP\" ]] && (git reset --soft \"HEAD^\") || (git add . && git commit -m \"WIP\")"

At first glance, this seemed like magic outside my comfort zone (when I see [[ in bash, I’m out), but it merely checks whether your latest commit was already called WIP. If it was, it does the soft reset, otherwise it creates the commit. So you can use git wip to toggle between the two states.

Personally, I am not a big fan of toggling, so I adapted his idea into two different aliased commands:

wip = !"git add . && git commit -m \"WIP\""
unwip = !"git reset --soft \"HEAD^\" && git status --short"

Through the git status, I can even see what my working directory looks like after un-WIPping:

$ git wip
[main 2836fcf] WIP
 2 files changed, 12 insertions(+), 37 deletions(-)

$ git unwip
M  README.md
M  src/posts/2023-01-04-git-reset-soft/post.md