How can I easily fixup a past commit?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
If the commit you want to fix is not the latest one, git commit --amend is no longer enough by itself. The clean Git workflow is to create a fixup commit that targets the older commit, then autosquash it during an interactive rebase. That keeps the final history tidy without manually copy-pasting patches around.
The Difference Between --amend And --fixup
Use git commit --amend when you only need to fix the most recent commit. It rewrites HEAD.
Use git commit --fixup when the mistake belongs to an earlier commit somewhere behind HEAD. A fixup commit says, in effect, "these staged changes should be folded into that older commit later."
Here is the common fixup flow:
In that example, abc1234 is the commit you want to repair.
Why This Workflow Is Better
A lot of people try to solve this by doing a long interactive rebase, manually marking commits as edit, then amending them one by one. That works, but --fixup is easier when you already know the target commit and only need to attach a small correction.
Git creates a new temporary commit with a message like:
Then git rebase -i --autosquash automatically moves that fixup commit next to the target and marks it for squashing.
That means:
- less manual editing in the rebase todo list
- fewer chances to reorder history incorrectly
- a cleaner and faster workflow
A Practical Example
Imagine this history:
You realize the validation change in a1b2c3d forgot one file. You are currently at f9e8d7c.
Stage the fix and create a fixup commit:
Now run:
Git opens the rebase plan with the fixup commit already placed next to a1b2c3d. Save and close the editor, and Git rewrites the branch so the forgotten file becomes part of the original validation commit.
After the rebase, the temporary fixup commit disappears from history.
When --amend Is Enough
If the commit you want to change is the last one, keep it simple:
You can keep the existing message or replace it. There is no reason to use --fixup for the latest commit unless you are deliberately building a later autosquash workflow.
Finding The Commit To Fix
If you do not know the hash, use a compact log:
If the commit is older or the branch is noisy, filtering by file can help:
You do not need the full 40-character hash. The short hash shown by git log --oneline is usually enough as long as it is unambiguous in the repository.
What About Pushed Commits
Fixup and autosquash rewrite history. That is normal and safe on a private branch you control. It is risky on a shared branch that other people may already have pulled.
If the branch has been pushed and shared:
- coordinate with collaborators before rewriting
- prefer
git push --force-with-leaseovergit push --force - avoid rewriting protected mainline branches unless your workflow explicitly allows it
If the original commit is already part of public history and should stay stable, git revert may be the better tool because it preserves history instead of rewriting it.
Related Shortcut: --fixup=amend
Modern Git also supports variants such as --fixup=amend:<commit>, which can be useful when you want to replace the original commit message as part of the autosquash flow. For simple content fixes, plain git commit --fixup <commit> is usually enough and easier to remember.
Common Pitfalls
- Using
git commit --amendwhen the target commit is notHEAD. - Rebasing from the wrong starting point.
abc1234^means "start just before the target commit." - Forgetting to stage the actual fix before creating the fixup commit.
- Force pushing rewritten history to a shared branch without checking who else is using it.
- Manually editing the rebase plan when
--autosquashcould have placed the fixup commit automatically.
Summary
- Use
git commit --amendonly for the latest commit. - Use
git commit --fixup <commit>for an older commit you want to repair. - Follow it with
git rebase -i --autosquash <commit>^to fold the fix into history cleanly. - This workflow is faster and safer than hand-editing a long interactive rebase.
- Be careful when rewriting commits that have already been shared with others.

