Safe git rebase -i for shared branches Jump to heading
Interactive rebasing on branches with multiple active contributors requires strict history-preservation discipline. The core rule is that published commits are immutable: once a commit has been pulled by another engineer, rewriting it forces them to reconcile divergent histories manually β a process that costs time, generates confusion, and can silently drop work. This page is a focused recipe for the specific scenario where you need to tidy local-only commits on a branch others are tracking, and it lives within the broader Interactive Rebase Workflows cluster, which covers the full decision boundary between rebase and merge.
When to use this approach Jump to heading
Apply this recipe when all of the following conditions are true:
- You are working on a shared branch (not a private feature branch nobody else has checked out).
- The commits you want to reorder, squash, or edit exist locally only β they are ahead of
origin/shared-branchand no teammate has pulled them yet. - A plain
git pushwould be rejected with a non-fast-forward error, or you want to clean up commits before requesting a code review. - You have write permission to force-push the branch (or access to a merge queue that accepts rebased history).
If the commits you want to rewrite have already been pulled by a colleague, this recipe does not apply. Use git revert instead β it appends an inverse commit without touching existing history.
If you only need to linearize a feature branch before opening a pull request on a branch you own, a straightforward git rebase main (without -i) is sufficient and carries less risk than an interactive session.
Shared-branch rebase: lifecycle diagram Jump to heading
The diagram below shows the safe path from a diverged branch state to a clean, force-pushed tip.
Step-by-step recipe Jump to heading
Step 1 β Fetch and measure divergence Jump to heading
Before any mutation, establish the exact state of the remote ref.
# Bring remote refs up to date without merging
git fetch origin
# Count commits each side has that the other lacks
# Output: <remote-ahead> <local-ahead>
git rev-list --left-right --count origin/shared-branch...HEAD
# Inspect local-only commits (those you may safely rewrite)
git log --oneline --graph --decorate origin/shared-branch..HEAD Verify: The right-hand number from --left-right --count is your local-only commit count. If the left-hand number is non-zero, a teammate pushed while you were working β you must rebase on top of the current remote tip before proceeding.
SAFETY WARNING: Never skip the fetch step. Rebasing against a stale local copy of
origin/shared-branchrelocates the problem rather than solving it β your rewritten commits will collide with the commits you missed.
Step 2 β Create a pre-rebase backup branch Jump to heading
A backup branch is a zero-cost safety net. Create it before every interactive rebase on a shared branch.
git switch shared-branch
# Hard-reset to confirmed remote tip (eliminates any local drift)
git reset --hard origin/shared-branch
# Snapshot the pre-rebase state
git branch shared-branch-pre-rebase Verify: git log --oneline -3 shared-branch-pre-rebase and git log --oneline -3 shared-branch should show identical SHAs at the tip.
SAFETY WARNING: The backup branch is forensic only. Do not push it, do not develop on it. If a teammate checks it out thinking it is a working branch, restoring from it becomes complicated.
Step 3 β Run the interactive rebase against the remote ref Jump to heading
The key constraint: rebase against origin/shared-branch, not against the local branch tip, which may itself be stale.
# Opens the editor with only local-only commits in the todo list
git rebase -i origin/shared-branch Inside the editor, apply pick, squash, fixup, reword, or edit to the commits shown. Every commit in the list is local-only β it is safe to reorder or squash these. If you recognise any SHA that you know a colleague has pulled (check your Slack/PR thread), stop and coordinate first.
For the squash and fixup actions in more detail β including how they interact with CI and commit counts β see the Squash and Fixup Strategies cluster.
Verify: After the editor closes, run git log --oneline origin/shared-branch..HEAD to confirm only your intended commits remain.
If a conflict surfaces during the rebase:
# Abort cleanly β no partial state is left behind
git rebase --abort
# Return to the pre-rebase tip and reconsider your approach
git checkout shared-branch
git log --oneline -5 Step 4 β Force-push with lease verification Jump to heading
--force-with-lease validates that the remote ref still points to the SHA you fetched in Step 1. If a teammate pushed between your fetch and your push, Git rejects the push instead of silently overwriting their commits.
git push --force-with-lease origin shared-branch Verify: The push output should confirm the remote ref was updated. If you see rejected β¦ stale info, fetch again, inspect the new commits, and rebase on top of them before pushing.
SAFETY WARNING: Never use bare
git push --forceon a shared branch. It bypasses the lease check entirely. A teammateβs commits pushed after your fetch are silently overwritten with no error.--force-with-leaseis the only acceptable option here. Even then, notify active contributors in your team channel before the push β they will need to reset their local copies to the new tip:git fetch origin && git reset --hard origin/shared-branch.
Step 5 β Validate CI and roll back if needed Jump to heading
After the push completes, confirm the branch is in the expected state and CI is clean.
git status
git log --oneline -5 origin/shared-branch If CI reports failures or the rebase introduced unintended changes, roll back using the reflog. The reflog retains every previous position of the branch pointer, even after a history rewrite.
# Find the SHA the branch pointed to before the rebase
git reflog show shared-branch | head -10
# Reset to the pre-rebase state (replace abc1234 with the correct SHA)
git reset --hard abc1234
# Validate the SHA before using it
git rev-parse abc1234^{commit}
# Push the rollback
git push --force-with-lease origin shared-branch Alternatively, if you still have the backup branch from Step 2, reset directly to it:
git reset --hard shared-branch-pre-rebase
git push --force-with-lease origin shared-branch Notify the team immediately after any rollback that restores prior history. Engineers who fetched the rewritten branch must reset their local copies.
Validation checklist Jump to heading
Run through these checks before closing your terminal:
Frequently Asked Questions Jump to heading
Can I use git rebase -i on a branch other people are actively using? Jump to heading
Yes, but only for commits that no teammate has pulled yet β those strictly ahead of origin/shared-branch. Rewriting commits they already have forces manual reconciliation on their end. Coordinate in your team channel before any force-push and have contributors reset their local branches afterwards: git fetch origin && git reset --hard origin/shared-branch.
What is the difference between --force and --force-with-lease? Jump to heading
--force overwrites the remote ref unconditionally. --force-with-lease first checks that the remote ref still points to the SHA you last fetched. If a teammate pushed between your fetch and your push, --force-with-lease rejects the operation, preserving their commits. Always use --force-with-lease on shared branches.
How do I recover if my rebase breaks the branch for the team? Jump to heading
Use git reflog show shared-branch to find the pre-rebase SHA, then git reset --hard <sha> followed by git push --force-with-lease. If you created the backup branch in Step 2, reset directly to that: git reset --hard shared-branch-pre-rebase && git push --force-with-lease. Notify teammates immediately β anyone who fetched the rewritten history must reset their local branch to the restored tip.
Related Jump to heading
- Interactive Rebase Workflows β the parent cluster covering the full rebase vs. merge decision boundary, reorder and squash patterns, and when each tool applies.
- Squash and Fixup Strategies β how to use
squash,fixup, andautosquashto collapse WIP commits before a pull request, and when to reach forgit revertvsgit reset. - When to Use git revert vs git reset β the decision matrix for choosing between history-preserving revert and history-rewriting reset, with shared-branch safety rules.
- Cherry-pick and Backporting β when selective commit application across branches is the right tool instead of a full rebase.