Skip to content
LatchkeyLatchkey home

git rebase --autosquash: Apply fixup! Commits

git rebase --autosquash recognizes commits whose messages start with "fixup!" or "squash!" and reorders them under the commit they reference, ready to fold in.

Paired with git commit --fixup, autosquash turns history cleanup into one command. With GIT_SEQUENCE_EDITOR set to true it runs unattended, which is what makes it usable in a CI cleanup step.

What it does

When you make a commit with git commit --fixup=<sha>, its message is "fixup! <original subject>". git rebase -i --autosquash reads those markers, moves each fixup/squash commit directly after its target, and marks it for folding, so the rebase plan is correct without manual editing.

Common usage

Terminal
git commit --fixup=abc1234
git commit --squash=abc1234   # also opens the editor to merge messages
# unattended (no editor) in a script
GIT_SEQUENCE_EDITOR=true git rebase -i --autosquash abc1234~1
# make autosquash the default
git config rebase.autosquash true

Options

Flag / configWhat it does
--autosquashAuto-reorder fixup!/squash! commits in an interactive rebase
--no-autosquashDisable even when rebase.autosquash is set
commit --fixup=<rev>Create a fixup! commit targeting <rev>
commit --squash=<rev>Create a squash! commit targeting <rev>
rebase.autosquash (config)Enable autosquash by default for -i
GIT_SEQUENCE_EDITOR=trueAccept the generated plan without an editor

In CI

autosquash only takes effect with interactive rebase (-i). To run it without a human, set GIT_SEQUENCE_EDITOR=true so the todo list is accepted as generated. As with any rebase, the result has new SHAs and needs --force-with-lease to push, which protected-branch rules may reject.

Common errors in CI

"hint: Waiting for your editor to close the file" means -i opened an editor in a non-interactive shell and hung; set GIT_SEQUENCE_EDITOR=true. fixup! commits left unsquashed in the final history mean autosquash was not enabled or the subject did not match the target commit. Conflicts still require --continue/--abort.

Using this in CI

CI checkouts are shallow and detached by default, which changes the answer this command gives you. Commands that read history, branch names, or tags need the checkout configured for it.

.github/workflows/ci.yml
- uses: actions/checkout@v4
  with:
    fetch-depth: 0   # history, tags, and git describe all need this

- run: |
    git rev-parse --is-shallow-repository   # expect false
    git rev-parse --abbrev-ref HEAD          # prints HEAD when detached

Frequently asked questions

git rebase --autosquash: Apply fixup! Commits?
Paired with git commit --fixup, autosquash turns history cleanup into one command. With GIT_SEQUENCE_EDITOR set to true it runs unattended, which is what makes it usable in a CI cleanup step.
What it does?
When you make a commit with git commit --fixup=<sha>, its message is "fixup! <original subject>". git rebase -i --autosquash reads those markers, moves each fixup/squash commit directly after its target, and marks it for folding, so the rebase plan is correct without manual editing.
In CI?
autosquash only takes effect with interactive rebase (-i). To run it without a human, set GIT_SEQUENCE_EDITOR=true so the todo list is accepted as generated. As with any rebase, the result has new SHAs and needs --force-with-lease to push, which protected-branch rules may reject.
Common errors in CI?
"hint: Waiting for your editor to close the file" means -i opened an editor in a non-interactive shell and hung; set GIT_SEQUENCE_EDITOR=true. fixup! commits left unsquashed in the final history mean autosquash was not enabled or the subject did not match the target commit. Conflicts still require --continue/--abort.

Related guides

References

Run this faster and cheaper on Latchkey managed runners - self-healing included. Start free → 30-day trial · No credit card