The Alias That Crossed the Atlantic
Once upon a time in the United States. An engineer typed a few lines into their shell config, probably on a rainy afternoon, probably with coffee going cold on the desk. It crossed an ocean, landed in France, made its way to me. I gave it to a friend at OVH, who shared it with his team. Somewhere right now, someone who has never heard of me is using it.
Some code just travels.
A clean history is better than anything
A git history is not a log of what you tried. It's a story of what you did and like any good story, it should be easy to follow.
Rebase is not just about changing the base of a branch. It's about reshaping your work into something readable. Squashing the "oops" commits. Reordering the steps. Making each commit atomic, intentional, self-contained. A well-crafted history makes a review a pleasure instead of an investigation. Your reviewer can go commit by commit and understand every change in context. That's a rare and generous thing to offer.
The fixup action in git rebase
When you run git rebase -i, you get a list of commits and a set of actions. You probably know pick, maybe squash, maybe drop. There's another one worth knowing: fixup.
Like squash, fixup merges a commit into the one above it. Unlike squash, it discards the commit message entirely. No prompt, no merge of messages. It just silently absorbs the change into the parent commit. Perfect for "fix typo", "forgot a file", "remove console.log" — commits that have no business existing in a final history.
pick a1b2c3 Add user authentication fixup d4e5f6 fix missing import pick g7h8i9 Add logout endpoint
The result: one clean "Add user authentication" commit, with the fix baked in. No trace of the mess.
How to use it
First, create your fixup commit and target it at the commit you want to amend:
git commit --fixup a1b2c3
Git will name it fixup! Add user authentication automatically. Then, when you rebase:
git rebase -i --autosquash main
The --autosquash flag reorders and marks the fixup commits automatically. You don't have to move anything by hand. The interactive editor opens already set up, ready to confirm.
The alias
Finding the hash of the commit you want to fix is the annoying part. You have to run git log, find the right line, copy the hash, type the command. It breaks the flow.
This alias fixes that:
[alias] fixup = "!git log -n 50 --pretty=format:'%h %s' --no-merges | fzf | cut -c -7 | xargs -o git commit --fixup"
It shows you the last 50 commits in fzf, you pick one interactively, and it creates the fixup commit in one move. No hash hunting. No context switching.
Add it to your ~/.gitconfig, and the workflow becomes:
git add -p # stage what you want to fix git fixup # pick the target commit in fzf git rebase -i --autosquash main # clean it all up
Three commands. A clean history. A happy reviewer.
And somewhere in Viriginia a talented engineer who started all of this.