Git Interactive Rebase: Editing and Reshaping Commit History
Use interactive rebase to inspect and edit the replay sequence: reorder, combine, reword, edit, drop, and autosquash commits, then verify the rewritten history.
Advanced
Open and inspect the rebase todo list
`git rebase -i <upstream>` opens an editable todo list instead of immediately replaying the selected commits with the default action. The todo list is an instruction sequence: each line identifies a commit and an action such as `pick`, `reword`, `edit`, `squash`, `fixup`, or `drop`. The list is processed in the displayed order.
git rebase -i main
# inspect the todo list before saving itQuick check
What is the primary purpose of the interactive rebase todo list?
A topic branch has commits that are candidates for replay.Git presents an editable sequence describing the replay actions.
Reorder commits with pick
Changing the order of `pick` lines changes the order in which the selected commits are replayed. Because later commits are replayed on the result of earlier ones, reordering can change commit identities and can also change whether the patches apply cleanly. It is a history rewrite, not a display-only sort.
# Example todo list before editing:
pick <A> add parser
pick <B> add tests
pick <C> update docs
# Reordered:
pick <A> add parser
pick <C> update docs
pick <B> add testsQuick check
What does moving two `pick` lines in the todo list do?
The todo list contains A followed by B.The edited todo list can replay B before A.
Combine commits with squash and fixup
`squash` combines the current commit with the preceding commit and opens the commit-message editor so their messages can be combined. `fixup` also combines the changes but discards the current commit's message, retaining the preceding commit's message. These actions therefore change both the number and identities of commits in the resulting history.
pick <A> implement feature
squash <B> add tests
fixup <C> tiny correctionQuick check
What is the key distinction between `squash` and `fixup`?
The todo list has a target commit followed by a correction commit.The correction can be combined with either message behavior explicitly selected.
Use reword to change a commit message
`reword` replays the commit but stops to let you change its commit message. The commit's content is preserved unless the operation itself causes another state change. Because the resulting commit is recreated, its object identity can change even when its tree content does not.
reword <A> old commit subject
pick <B> later commitQuick check
What does `reword` primarily change?
A selected commit has an unwanted message.The replay can recreate it with a corrected message.
Use edit to stop at a commit
`edit` tells interactive rebase to stop after applying the selected commit. At that point the commit has been replayed and the operation is paused, allowing you to amend the commit or otherwise change the state before continuing. `git rebase --continue` belongs to V449's operational control boundary; this lesson focuses on why the todo action creates the intentional stop.
edit <A> commit to revise
pick <B> later commit
# after Git stops:
git status
git commit --amend
git rebase --continueQuick check
Why would an interactive rebase todo line use `edit`?
The commit needs a controlled content or metadata correction.The rebase stops at that commit before continuing the remaining sequence.
Drop a commit deliberately
`drop` removes a selected commit from the replay sequence. Deleting a todo line can also omit a commit, but the explicit `drop` action communicates that the omission is intentional. The result is a history without that replayed commit; later commits are still processed according to the remaining todo sequence.
pick <A> keep this
drop <B> remove this
pick <C> keep this laterQuick check
What does an explicit `drop` action mean?
The todo list contains a commit that should not remain in the rewritten sequence.Git proceeds without replaying that commit.
Use autosquash for fixup and squash commits
Interactive rebase can automatically rearrange commits created with `git commit --fixup`, `--fixup=amend:`, `--fixup=reword:`, or `--squash`. With `--autosquash`, matching `fixup!`, `squash!`, or `amend!` commits are moved next to their target and their todo actions are changed accordingly. The official documentation recommends creating these markers with the corresponding `git commit` options rather than hand-writing their messages.
git commit --fixup=<target>
git rebase -i --autosquash mainQuick check
What does `--autosquash` change?
A fixup or squash marker commit exists.Interactive rebase can arrange it next to its target automatically.
Verify the rewritten history
Interactive rebase should be verified by inspecting both the resulting graph and the exact commit identities/messages that matter. If commits were reordered, combined, reworded, edited, or dropped, compare the resulting ancestry and commit count with the intended todo sequence. The remote remains unchanged until a separate publication operation.
git log --oneline --graph --decorate --all
git rev-list --count main..HEAD
git show -s --format='%H%n%s' HEADQuick check
What is the strongest verification after a history-editing interactive rebase?
The interactive rebase has completed.The resulting history is checked against the intended transformation.
Practice what you learned
Use the dedicated Git code-completion exercise for this lesson.
Thanks for your feedback.
Mark this learning resource complete to track your learning progress.