# Combining git commit --fixup and git rebase --autosquash for Cleaner Commits

> Learn to combine git commit --fixup and git rebase --autosquash for cleaner commits. Automatically squash corrections into original commits for a linear history.

- Repository: [Tim Green/github-cheat-sheet](https://github.com/tiimgreen/github-cheat-sheet)
- Tags: how-to-guide
- Published: 2026-03-06

---

**Use `git commit --fixup` to mark correction commits and `git rebase --autosquash` to automatically squash them into the original commits, producing a clean, linear history without manual todo editing.**

The `tiimgreen/github-cheat-sheet` repository documents this workflow in [`README.md`](https://github.com/tiimgreen/github-cheat-sheet/blob/main/README.md) (lines 929-936), with translations available in [`README.zh-cn.md`](https://github.com/tiimgreen/github-cheat-sheet/blob/main/README.zh-cn.md), [`README.zh-tw.md`](https://github.com/tiimgreen/github-cheat-sheet/blob/main/README.zh-tw.md), [`README.ja.md`](https://github.com/tiimgreen/github-cheat-sheet/blob/main/README.ja.md), and [`README.ko.md`](https://github.com/tiimgreen/github-cheat-sheet/blob/main/README.ko.md). Combining **git commit --fixup** and **git rebase --autosquash** allows you to amend previous commits without manually resolving complex rebase todo lists or risking accidental merges with unrelated changes. This technique ensures your `git log` remains readable while preserving the logical grouping of related code changes.

## How git commit --fixup Works

According to the source documentation, `git commit --fixup` creates a temporary correction commit that targets a specific previous commit. When you execute:

```bash
git commit --fixup=abcde

```

Git generates a new commit whose message is automatically prefixed with `fixup!` followed by the subject line of the target commit `abcde`. This commit serves as a placeholder meant to be squashed into the original commit during a subsequent rebase operation. The `--fixup` flag also sets the *GIT_REFLOG_ACTION* environment variable to clearly mark the commit's purpose in the reflog.

## How git rebase --autosquash Works

The `--autosquash` flag for `git rebase` automates the tedious aspects of interactive history rewriting. When enabled, Git scans the commit sequence for messages beginning with `fixup!` or `squash!`. It then automatically **reorders** these fixup commits to appear immediately after their target commits and changes the command from `pick` to `fixup` in the todo list. When the interactive rebase editor opens, the commits are already staged for automatic squashing—simply save and close to complete the merge.

## Why Combine These Commands?

Using **git commit --fixup** with **git rebase --autosquash** provides three distinct advantages over manual rebasing:

- **Speed** – You avoid remembering exact commit hashes or manually editing rebase todo lists to reorder and squash commits.
- **Safety** – The autosquash mechanism guarantees fixup commits are applied only to their intended targets, preventing accidental merges with unrelated changes.
- **Clean history** – The final result contains single, logically grouped commits that make code review and `git log` output significantly easier to read.

## Step-by-Step Workflow

### Identify the Target Commit

First, locate the commit you need to amend using the repository history:

```bash
git log --oneline --decorate

```

Note the commit hash (e.g., `abcde`) that requires correction.

### Create the Fixup Commit

Make your required changes in the working tree, then create a fixup commit targeting the specific hash:

```bash
vim src/main.py
git commit --fixup=abcde

```

This creates a commit with the message `fixup! [original subject line]`, clearly marking it for later squashing.

### Execute the Autosquash Rebase

Initiate the rebase from the parent of your target commit with the autosquash flag:

```bash
git rebase abcde^ --autosquash -i

```

When the interactive editor opens, Git will have already reordered the fixup commit directly after the target and set the action to `fixup`. Save and close the editor—Git automatically squashes the fixup content into the original commit via a fast-forward merge.

### Verify the Results

Confirm the fixup was successfully merged and the history is linear:

```bash
git log --oneline --decorate

```

The temporary `fixup!` commit should no longer appear as a separate entry; its changes are now part of the original commit.

## Underlying Mechanics

During the rebase operation, `--autosquash` parses the todo list and inserts `fixup` lines immediately following their respective targets. When the rebase completes, Git performs a fast-forward merge of the fixup content into the original commit. This process preserves the original commit's metadata—including author name, email, and timestamp—while updating the tree content. The *GIT_REFLOG_ACTION* variable set during the initial `git commit --fixup` operation ensures these actions are clearly tracked in the repository's reflog.

## Summary

- **`git commit --fixup=<hash>`** creates a marker commit prefixed with `fixup!` that targets a specific previous commit.
- **`git rebase --autosquash`** automatically detects these marker commits, reorders them after their targets, and prepares them for squashing without manual todo editing.
- This combination ensures **speed** and **safety** while maintaining a **clean, linear history**.
- The underlying mechanics use fast-forward merging and reflog actions to preserve commit metadata while updating code content.

## Frequently Asked Questions

### What is the difference between `fixup!` and `squash!` in Git?

Both prefixes trigger autosquash reordering, but they behave differently during the rebase. A commit marked with `fixup!` is automatically squashed into the target commit and its message is discarded. A commit marked with `squash!` is also combined with the target, but Git pauses to let you edit the final commit message, allowing you to combine or rewrite the descriptions.

### Can I use `--autosquash` without interactive mode?

No, `--autosquash` requires the `-i` (interactive) flag to function. The autosquash mechanism works by pre-populating and modifying the interactive rebase todo list before the editor opens. Without interactive mode, Git has no opportunity to reorder the commits or set the fixup commands.

### How do I fixup multiple commits at once?

You can create multiple fixup commits targeting different original commits, or even multiple fixups for the same target. Run `git commit --fixup=<hash>` repeatedly for each change. When you execute `git rebase --autosquash -i`, Git will reorder all fixup commits to appear immediately after their respective targets, stacking multiple fixups in sequence before the final squash operations.

### Does using fixup and autosquash change the original commit's SHA?

Yes, the original commit receives a new SHA-1 hash because its tree content changes when the fixup is merged. However, Git preserves the original commit metadata including the author name, email, and original timestamp. The reflog maintains the history of these operations via the *GIT_REFLOG_ACTION* variable set during the fixup commit creation.