Interactive Rebase
Git's tool for rewriting a series of commits before sharing them, reordering, combining, splitting, and rewording them so the history tells a clear story rather than recording every false start.
Interactive rebase is a Git command, git rebase -i, that lets a developer rewrite a series of their own commits before sharing them. It opens a list of recent commits in a text editor, one per line, and the developer edits the list to say what should happen to each. Git then replays them according to those instructions, using the same machinery as an ordinary Rebase.
The main instructions:
- pick keeps a commit as it is. Reordering the lines reorders the commits.
- reword keeps the change but edits the message.
- squash and fixup fold a commit into the one before it, keeping or discarding its message.
- edit pauses on a commit so it can be amended or split into several.
- drop, or deleting the line, removes a commit entirely.
The purpose is a readable history. Real work is messy: a feature commit followed by "fix typo," "actually fix it," and "address review comments." Each of those is noise to a future reader trying to understand the change, and noise to tools that rely on history. Rewritten, the same work becomes a few atomic commits, each a coherent step that builds and passes tests. That pays off when Git Bisect searches for a regression, since every commit it lands on works, and when someone reverts one piece.
Fixup commits make this routine. Running git commit --fixup with a target commit creates a commit marked to be folded into that one later. Rebasing with --autosquash moves each fixup into place automatically, so small corrections made during Code Review can be recorded separately for reviewers and merged into the right commits before landing.
Rewriting history has a hard rule: don't rewrite commits other people have already built on. Rebasing replaces commits with new ones that have different identifiers. Anyone holding the old versions now has diverged history, and pushing the rewrite requires overwriting the remote branch; see Force Push. Most teams rewrite freely on private branches and never on shared ones. Lost commits aren't truly gone for a while, since Git records where branches pointed; see Reflog.
Teams disagree about how much to care. Some squash every pull request into one commit at merge time, which makes cleanup unnecessary but discards the intermediate steps. Others want each commit reviewed and kept, which makes interactive rebase part of daily work. Workflows built on chains of small dependent branches lean on it heavily, since changing an early commit means replaying everything above it; see Stacked Pull Requests.
Replaying commits can hit a Merge Conflict at each step, and each must be resolved before the next. Moving a single commit to another branch is a smaller operation; see Cherry-Pick.
See also2
Staging Area
The intermediate snapshot in Git between the working files and the next commit, which lets a developer choose exactly which changes go into each commit, down to individual lines.
Version Control & Delivery15 connections
Detached HEAD
The Git state in which the current checkout points directly at a commit rather than a branch, harmless for looking around but a trap for new work, since commits made there belong to no branch and can quietly disappear.
Version Control & Delivery11 connections
Linked from7
- Cherry-PickVersion Control & Delivery
Copying the change from one commit onto another branch as a new commit, the standard way to backport a fix without merging everything else that came with it.
- Commit MessageVersion Control & Delivery
The note attached to each change in version control, conventionally a short summary line and a body explaining why, which becomes the main record of intent for anyone who later wonders why the code is the way it is.
- Detached HEADVersion Control & Delivery
The Git state in which the current checkout points directly at a commit rather than a branch, harmless for looking around but a trap for new work, since commits made there belong to no branch and can quietly disappear.
- Force PushVersion Control & Delivery
Overwriting a remote branch with local history that doesn't contain it, the operation that makes rewritten history shareable and silently deletes other people's work when used carelessly.
- ReflogVersion Control & Delivery
Git's private record of everywhere HEAD and each branch has pointed, the safety net that makes a botched reset, rebase, or deleted branch recoverable for weeks.
- Stacked Pull RequestsVersion Control & Delivery
A chain of dependent changes, each reviewed separately and merged in order.
- Staging AreaVersion Control & Delivery
The intermediate snapshot in Git between the working files and the next commit, which lets a developer choose exactly which changes go into each commit, down to individual lines.