---
title: "Git Rebase Cheatsheet"
slug: "git-rebase"
category: "cheatsheets"
tags: ["cheatsheets", "git", "rebase", "version-control", "reference", "workflow"]
status: "stable"
last_updated: 2026-05-14
summary: "Interactive rebase commands, rebase --onto patterns, and conflict resolution steps for keeping a clean linear history."
related:
  [
    "[[coding/git]]",
    "[[cheatsheets/git-commands]]",
    "[[tooling/github]]",
    "[[tooling/claude-code-workflow]]",
    "[[cheatsheets/bash-one-liners]]",
    "[[cheatsheets/index|Cheatsheets]]",
  ]
---

## Overview

Rebase replays commits on top of a new base. Use it to linearize history before merging, to clean up a feature branch before review, or to move a branch to a different starting point. Rebase rewrites commit SHAs; only use it on commits that have not been pushed to a shared branch. For the broader commit hygiene rules and when to prefer merge over rebase, see [[coding/git]]. For the full command reference, see [[cheatsheets/git-commands]].

## Interactive rebase commands

`git rebase -i HEAD~N` opens an editor listing the last N commits, one per line. Change the verb to apply an operation.

| Command  | Short  | What it does                                                                         |
| -------- | ------ | ------------------------------------------------------------------------------------ |
| `pick`   | `p`    | Keep the commit as-is.                                                               |
| `reword` | `r`    | Keep the commit; open editor to change the message only.                             |
| `edit`   | `e`    | Pause after applying the commit; lets you amend files or split the commit.           |
| `squash` | `s`    | Combine with the preceding commit; open editor to merge the commit messages.         |
| `fixup`  | `f`    | Like `squash` but discard this commit's message entirely.                            |
| `drop`   | `d`    | Remove the commit from history.                                                      |
| `exec`   | `x`    | Run a shell command after the preceding commit; useful for running tests per commit. |
| `break`  | `b`    | Pause the rebase for manual intervention; resume with `git rebase --continue`.       |
| `label`  | `l`    | Create a label at the current point; used for merging branches in a rebase script.   |
| `merge`  | (none) | Create a merge commit during an interactive rebase sequence.                         |

```
# Example: rebase -i HEAD~4
pick a1b2c3 Add user model
squash d4e5f6 Fix typo in user model
reword 7g8h9i Add auth middleware
fixup 0j1k2l WIP: auth tests
```

After saving and closing, git applies the commits top-to-bottom, pausing for message edits or conflicts.

## Rebase --onto patterns

`--onto` lets you transplant a range of commits to an arbitrary new base.

| Goal                                     | Command                                                        |
| ---------------------------------------- | -------------------------------------------------------------- |
| Move branch off old base to new base     | `git rebase --onto <newbase> <oldbase> <branch>`               |
| Drop first N commits from a branch       | `git rebase --onto HEAD~N HEAD~N <branch>`                     |
| Move a sub-branch onto main directly     | `git rebase --onto main feature-base sub-feature`              |
| Replay single commit onto another branch | `git cherry-pick <sha>` (simpler than `--onto` for one commit) |

```bash
# Context: main <- feature-a <- feature-b
# Goal: move feature-b directly onto main, dropping feature-a

git rebase --onto main feature-a feature-b

# Before: main -- A -- B -- C (feature-a)
#                             \-- D -- E (feature-b)
# After:  main -- A -- B -- C (feature-a)
#              \-- D' -- E' (feature-b)
```

## Conflict resolution

Conflicts arise when replayed commits touch the same lines as the new base.

| Step                     | Command                 | Purpose                                                                                    |
| ------------------------ | ----------------------- | ------------------------------------------------------------------------------------------ |
| 1. See conflicting files | `git status`            | Lists files with conflict markers.                                                         |
| 2. Open file and resolve | Edit the file           | Remove `<<<<<<<`, `=======`, `>>>>>>>` markers; keep the correct version.                  |
| 3. Stage the resolution  | `git add <file>`        | Mark conflict resolved.                                                                    |
| 4. Continue the rebase   | `git rebase --continue` | Apply the next commit.                                                                     |
| 5. Abort if stuck        | `git rebase --abort`    | Restore original state; safe escape hatch.                                                 |
| 6. Skip a commit         | `git rebase --skip`     | Drop the conflicting commit; only use when the commit is genuinely empty after resolution. |

```bash
# During conflict
git status
# both modified: src/auth.ts

# Resolve in editor, then:
git add src/auth.ts
git rebase --continue
```

For complex conflicts, `git mergetool` opens a three-way diff (yours, theirs, base). Configure with `git config merge.tool vimdiff` or a GUI tool.

## Autosquash workflow

Mark commits as fixups at creation time; collapse them automatically at rebase.

| Command                           | Purpose                                               |
| --------------------------------- | ----------------------------------------------------- |
| `git commit --fixup=<sha>`        | Create a `fixup! <original message>` commit.          |
| `git commit --squash=<sha>`       | Like `--fixup` but preserves the message for editing. |
| `git rebase -i --autosquash main` | Automatically reorder and apply fixup/squash commits. |

```bash
# Workflow
git commit -m "Add login endpoint"      # sha abc123
# later, fix a bug in that commit:
git commit --fixup=abc123
git rebase -i --autosquash main         # fixup commit is auto-moved and applied
```

Configure `rebase.autoSquash = true` globally to make `--autosquash` the default for all interactive rebases.

## Safety flags

| Flag                 | Effect                                                                                       |
| -------------------- | -------------------------------------------------------------------------------------------- |
| `--no-ff`            | Prevent fast-forward; always create a merge commit (used with merge, not rebase).            |
| `--force-with-lease` | Push a rebased branch safely; aborts if the remote has new commits since your last fetch.    |
| `--update-refs`      | Auto-update branch pointers for any branches pointing at rebased commits; useful in a stack. |
| `--rebase-merges`    | Preserve merge commits during interactive rebase.                                            |

```bash
# Push a rebased branch without clobbering someone else's push
git push --force-with-lease origin feature/auth
```

## Common gotchas

- Rebasing shared branches forces every collaborator to recover with `git reset --hard`. Only rebase commits that exist on your local branch or a branch only you use.
- Interactive rebase of a range that includes merge commits will lose the merge structure unless you pass `--rebase-merges`. By default it linearizes everything.
- `git rebase --abort` fully restores the pre-rebase state including the branch pointer; it is always safe to run if you are stuck.
- `git rebase --skip` drops the commit, not just the conflict. Use it only when the commit's changes were already applied by the base (e.g., a cherry-pick that was also merged).
- Stash or commit all changes before starting a rebase. A dirty working tree will abort the rebase immediately.
- After a forced push to a remote feature branch, teammates who have checked it out must run `git reset --hard origin/<branch>` or `git pull --rebase`.

## Related

- [[coding/git]]
- [[cheatsheets/git-commands]]
- [[tooling/github]]
- [[tooling/claude-code-workflow]]
- [[cheatsheets/bash-one-liners]]
- [[cheatsheets/index|Cheatsheets]]
