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-branch and no teammate has pulled them yet.
  • A plain git push would 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.

Safe interactive rebase lifecycle on a shared branchFive stages: fetch and diagnose divergence, create backup branch, run git rebase -i, force-push with lease, validate or rollback.1. Fetch &Diagnoserev-list --left-right2. BackupBranchgit branch …-pre-rebase3. RebaseLocal-onlygit rebase -i origin/…4. Pushwith Lease--force-with-leaseCIOK?βœ“Doneyesno5. Rollback via refloggit reset --hard <pre-rebase SHA>git push --force-with-leaseConflict β†’ git rebase --abortrestore from backup branchconflict

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-branch relocates 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 --force on 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-lease is 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.


  • 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, and autosquash to collapse WIP commits before a pull request, and when to reach for git revert vs git 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.