After committing, I always like to go through the diff before pushing the changes upstream. Just to make sure that everything is as it should be. Well, quite often I still spot some typos, commented out code that I was supposed to remove or some other minor things that need to be fixed. So I ended up running the same exact commands time and time again. First new commit for the fixes and then interactive rebase to squash the changes to the previous commit. Perfect opportunity to make an alias to save those precious keystrokes.
fixlast = !git commit -a --fixup=HEAD && GIT_EDITOR=true git rebase -i --autosquash HEAD~2
You can add the aliases to, for instance, your ~/.gitconfig file. With this alias you can easily autosquash changes to the previous commit by running git fixlast.
So let's break it down quickly. To easily run multiple commands I've used ! to run shell commands instead of only git sub-commands. The first part takes all changes and creates a fixup commit for the previous commit, HEAD. The fixup argument adds fixup! prefix to the commit message which will be recognized by the autosquash later.
The second part starts interactive rebase and tells git to process all fixup and squash commits (--autosquash argument). The HEAD~2 takes two topmost commits to the rebase.
Normally, the interactive rebase opens an editor, but in this case we really just want to accept the autosquash without any manual selections. To do so GIT_EDITOR environment variable is set to true (i.e. /bin/true application). So when git wants to open the rebase editor, it just receives success return code immediately and carries on with the rebase. That's all there is to it.
Edit: Just realized that the solution above is bit overly complicated. You could accomplish the same with --amend commit flag. Still, using the GIT_EDITOR environment variable can be used to avoid the amend editor pop up.
This was also posted on my blog. Check it out if you're interested.