Interactive git commit --fixup + autosquash in one keystroke.
Stage the changes you want folded into a previous commit, run fup, pick the
target commit with the arrow keys, hit Enter. fup creates the fixup commit,
autosquashes the history, and restores any unstaged leftovers via the stash.
Requires Go 1.24+ and git on PATH.
go install github.com/anttti/fup@latestOr from a checkout:
git clone https://github.com/anttti/fup
cd fup
go build -o fup .git add -p # stage the changes destined for an older commit
fup # pick the target, doneKeys in the picker:
| Key | Action |
|---|---|
↑ / k |
move up |
↓ / j |
move down |
pgup / pgdn |
page up / down |
g / G |
top / bottom |
enter |
fix up into commit |
q / esc |
cancel |
- Checks you're in a git work tree, no rebase/merge/cherry-pick is in progress, and there's at least one staged change.
- Shows the last N commits of
HEAD(default 20,-n Nto override). - On selection:
- If you have unstaged tracked changes or untracked files, stashes them
with
git stash push --keep-index --include-untracked. git commit --fixup=<sha>.git rebase -i --autosquash <sha>^withGIT_SEQUENCE_EDITOR=:so the todo list is accepted non-interactively.git stash popif step 1 actually stashed anything.
- If you have unstaged tracked changes or untracked files, stashes them
with
-n N— number of commits shown in the picker (default20).
If autosquash can't cleanly apply the fixup, fup leaves the rebase in
progress and keeps the stash intact. Resolve the conflict, then:
git rebase --continue
git stash pop # only if fup told you it stashedDoing this by hand is five commands and a SHA lookup; doing it wrong leaves a
stash dangling or a fixup! commit in your history. fup is a thin wrapper
around git — no go-git, no magic — so your hooks and config apply as usual.