As developers, we've all stumbled upon these disconcerting situations while using Git:
Many people will just commit ++code>git commit -m "fix tests"++/code> (don’t worry we all do it).
But there’s a cleaner way to do so using fixup commits and a rebase interactive. And even better: we can automate it all!
You can jump at the end of the article if you only want the final command, but I’d recommend walking through it to understand what we’re using. It’s better to abstract once you know what’s going it!
Here's how you can use our command:
If you are not interested by the implementation, you can jump right off at the end of the article!
The only prerequisite is ++code>fzf++/code>.
++code>fzf++/code> is an incredible tool that has one single purpose: it takes a list as input and returns an item you selected as output (or multiple items). We'll be using it to interactively select a commit.
It takes the input through ++code>stdin++/code> (usually it means you’ll be using ++code>|++/code> in a shell), and returns the result through ++code>stdout++/code> (means ++code>|++/code> again as an output).
Here are the steps:
++pre>++code class="language-bash hljs">git rebase --autosquash -i $COMMIT_HASH^++/code>++/pre>
++pre>++code class="language-bash hljs">GIT_SEQUENCE_EDITOR=: git rebase --autosquash -i $COMMIT_HASH^++/code>++/pre>
++pre>++code class="language-bash hljs">GIT_SEQUENCE_EDITOR=: git rebase --autostash --autosquash -i $COMMIT_HASH^++/code>++/pre>
Add the following alias to your ++code>~/.gitconfig++/code> and that’s it!
++pre>++code>[alias]
# Amend into a past commit using fzf
# Stage your changes `git add -p`, then run `git autofixup` and choose the target commit
autofixup = "!f() { \
COMMIT_HASH=$(git log --pretty=oneline | fzf | awk '{print $1}'); \
git commit --fixup $COMMIT_HASH; \
GIT_SEQUENCE_EDITOR=: git rebase --autostash --autosquash -i $COMMIT_HASH^; \
}; f"++/pre>++/code>
This alias is a very valuable tool to help you having clean commits. You can modify past commits so easily that it becomes a natural thing. It just takes a second. It's a tool that many of us adopted at BAM!
I hope it will be useful to you too!
On a final note, you can implement many interactive commands using ++code>fzf++/code>. Selecting a commit to do something is a classic, you can think of many other commands (like selecting a commit to show its diff, using ++code>git show $COMMIT_HASH++/code>). Be creative 🙂