Interactive rebase is useful when a private branch tells the wrong story: a fix is split across noise commits, a message hides the intent, or an accidental file was added and removed in separate steps. It is dangerous when treated as cosmetic formatting after other people or automation have based work on the existing commit IDs.
The decision comes before the command. Rewrite only history whose consumers are known and coordinated. Then preserve the old tip, edit the smallest range, and compare the resulting patch series rather than trusting that a conflict-free rebase preserved meaning.
Decide whether the history is still private
A rebase creates new commits. Even when file content is unchanged, commit IDs, parent relationships, and possibly timestamps change. The git rebase documentation explicitly warns against rewriting a branch that others have based work on.
Treat a branch as shared when any of these are true:
- another developer has pulled it or opened dependent work;
- CI, deployment, audit, or release records identify its commit IDs;
- a review contains comments anchored to the existing patch series;
- the repository policy forbids force updates;
- a tag or release points into the range.
In those cases, prefer follow-up commits or a merge strategy that preserves published identities. If the branch is yours alone and the remote is only a backup, coordinate the rewrite and use the repository's normal protected update process.
Establish the exact range and a recovery reference
Start from a clean working tree. Identify the target branch's merge base instead of guessing a count such as HEAD~7:
git status --short --branch
git fetch origin
git merge-base HEAD origin/main
git log --oneline --decorate origin/main..HEAD
git branch backup/invoice-export-before-rebase HEAD
The backup branch makes the original series easy to inspect and restore. It is safer than relying only on memory or on a reflog entry whose retention is time-limited.
Review both committed and uncommitted state before continuing. Interactive rebase normally expects a clean tree. If unrelated edits exist, commit them coherently on another branch or preserve them through an explicit, verified workflow; do not hide a mixed working tree behind an unexplained stash.
Edit commits according to intent
Launch the editor from the verified base:
git rebase -i origin/main
The todo list is ordered from older to newer commits. Use each action for a concrete reason:
rewordchanges a message while preserving the patch's role.fixupfolds a corrective commit into the commit it repairs and discards the fixup message.squashcombines commits while allowing their messages to be edited.editpauses so the selected commit can be amended or split.dropremoves a commit and therefore requires evidence that its effect is obsolete or duplicated.
Avoid turning an entire branch into one commit by default. A useful series keeps independently reviewable changes separate, orders prerequisites before consumers, and allows a future maintainer to revert one decision without reverting unrelated work.
When splitting a commit, pause with edit, reset the commit while keeping its changes available, then stage and commit coherent pieces. Inspect the index before every new commit. The exact reset mode changes which state is retained, so use it only after confirming the repository state and the relevant Git documentation.
Resolve conflicts as a new integration decision
A rebase replays each selected patch onto a new parent. Conflict markers show that Git could not combine those states automatically; they do not identify the correct product behavior.
At every stop:
git status
git diff
git diff --staged
Reconstruct the intent of the rebased commit and the target branch. Resolve the smallest coherent unit, stage it, run the nearest relevant checks, and continue:
git add <resolved-path>
git rebase --continue
If the chosen approach is wrong or the conflict scope is unclear, return to the original branch state:
git rebase --abort
Do not use “ours” or “theirs” as a blind shortcut. During rebase, those labels can be counterintuitive because commits are being replayed onto a new base. Inspect the actual content and ancestry.
Compare the old and new patch series
A passing final tree is not sufficient. Reordering commits can create intermediate commits that do not build, and an accidental conflict resolution can preserve the endpoint while losing a meaningful step.
Compare the backup series with the rewritten one:
git range-diff origin/main...backup/invoice-export-before-rebase origin/main...HEAD
git diff --stat backup/invoice-export-before-rebase..HEAD
git diff backup/invoice-export-before-rebase..HEAD
git log --oneline --decorate origin/main..HEAD
git range-diff compares two commit series and helps expose dropped, added, or materially changed patches. The direct tree diff should normally be empty when the goal was only to reorganize history. If it is not empty, every difference needs an explanation and testing.
Run the project's checks against the final branch and, when repository policy requires buildable commits, against each rewritten commit. A clean endpoint does not prove that git bisect, cherry-picking, or partial review will work across the series.
Update the remote without overwriting new work
Fetch again immediately before updating a remote branch. If the remote tip changed since the rewrite began, stop and reconcile with the contributor or automation that changed it.
When a coordinated force update is permitted, --force-with-lease is safer than an unconditional force because it refuses the update when the remote reference no longer matches the expected value:
git fetch origin
git push --force-with-lease origin HEAD:feature/invoice-export
This is a guard against one class of race, not proof that rewriting is harmless. Branch protection, open reviews, downstream branches, and deployment records still matter.
Keep the backup branch until the remote update, CI checks, and review are stable. Interactive rebase is complete when the rewritten series is easier to reason about, equivalent where equivalence was intended, and safe for every known consumer of the old history.
Was this guide useful?
Your rating helps us prioritize clearer, more practical technical content.
Review diffs, run checks, and prepare the release in Arezgit.
Keep Git review, security scanning, API checks, database inspection, and release preparation together in one local desktop application.
Explore Arezgit