Chapter 5.5 — When NOT to Rebase☕ 14 min read

When NOT to Rebase

Rebase tumhari marzi ki apni local branch pe. Shared branch pe rebase = team ka chaos.

01Rule #1: Shared Branches

The Golden Rule of Rebase: NEVER rebase commits that have been pushed to a shared branch.

Shared branches include main, develop, release/*, or any branch that multiple people have pulled.

When you rebase, you rewrite history. Old commits are destroyed and replaced with new ones. The old commit hashes no longer exist — they are replaced by new hashes for the same changes.

If someone else has based work on those old commits, their repository now has divergent history — their local branch and the remote branch have fundamentally different commit objects.

Result: teammates can't push, can't pull, get duplicate commits, or lose work. The entire team's workflow grinds to a halt while everyone recovers.

The ONLY safe rebase: your own local feature branch that NO ONE else has pulled.

# SAFE: Rebase your own unpushed feature branch
git checkout my-feature  # only you work on this
git rebase origin/main  # update with main
git push --force-with-lease origin my-feature  # force push OK

# DANGEROUS: Rebase a shared branch
git checkout develop  # 5 people work on this
git rebase main       # history rewritten
# Now all 5 people have broken local repos
# Their next git pull will fail or create duplicates

# NEVER: Rebase main
git checkout main
git rebase feature
# You just rewrote PRODUCTION history
# Every developer's local main is now divergent
# CI/CD pipelines may break
# This is a career-limiting move
02Rule #2: Open PRs

Scenario: You rebase develop. Three teammates have already pulled the old develop.

Your rebase creates new commits (new hashes) on the remote. The old commits still exist in your teammates' local repos.

When they run git pull, Git tries to merge old and new commits → DUPLICATE COMMITS. The same changes appear twice in the history because Git sees the old and new commits as different objects.

Or: git pull fails with divergent branches, and they must run git reset --hard origin/developLOSE LOCAL COMMITS that were not yet pushed.

The damage cascades: every person who pulled the old branch must manually recover. Some will lose work. Some will create duplicates. Some will waste hours debugging what went wrong.

This is why branch protection rules exist — to prevent force pushes to shared branches.

💡 If you accidentally rebase a shared branch: 1) Don't push! 2) Run git rebase --abort if still in progress 3) Run git reset --hard origin/develop to restore the shared history 4) If already pushed: notify team immediately, provide recovery instructions.
03Rule #3: Tagged Commits

Your PR was approved. CI passed. Now you want to rebase to "clean up" before merging. Stop right there.

Rebasing changes the commit hashes, which means:

  • CI results are now INVALID — they tested old hashes, not new ones
  • The code review approved OLD commits, not the rebased ones
  • If rebase introduced subtle changes (unlikely but possible during conflict resolution), nobody reviewed them
  • Reviewer must re-approve, wasting their time and breaking the approval workflow

CORRECT: merge as-is, or if you must update, use git merge origin/main instead of rebase.

Exception: your team has an explicit "rebase before merge" policy and reviewers know to re-check after rebase.

# WRONG: Rebase after PR approval
# PR approved, CI green, ready to merge
git checkout feature
git rebase origin/main  # DON'T DO THIS
git push --force-with-lease origin feature
# Now: CI must re-run, reviewer must re-approve
# What if rebase subtly changed the code?

# CORRECT: Merge as-is or merge main into feature
# Option 1: Just merge (if no conflicts expected)
git checkout main
git merge feature  # preserve approved code

# Option 2: Update feature safely
git checkout feature
git merge origin/main  # merge commit, no history rewrite
git push origin feature
# CI re-runs on the merge commit (expected)
# But your approved commits are untouched

# Option 3: Rebase BEFORE review (correct timing)
# Write code → rebase → push → create PR → review → merge
04The Divergence Disaster

Even on a feature branch, if someone else has pulled your branch, rebase breaks their work.

"I'm the only one on this branch" — are you SURE? Check with the team before assuming.

  • Pair programming: if your pair has a local copy, rebase will break their repo too
  • CI systems: if CI checked out your branch for testing, rebase invalidates those results
  • Code reviewers: if someone pulled your branch to review locally, their copy diverges

Safe to rebase: commits that have NEVER been pushed (100% local).

Safe-ish: commits you pushed but confirmed no one else pulled (check with team).

Not safe: any commit someone else has based work on.

# Check if anyone else is on this branch
git branch -r --contains abc1234  # use your commit hash
# If only origin/feature shows up, you might be alone
# But check with team in Slack/Teams anyway!

# Safe rebase workflow:
# 1. Verify you're the only one
git push --force-with-lease origin feature
# --force-with-lease will FAIL if someone pushed new commits
# This is your safety net!

# If you're NOT alone, use merge instead:
git merge origin/main  # safe for shared branches
05Safe Alternatives

If you haven't pushed yet: git rebase --abort (if still in progress) or git reset --hard ORIG_HEAD.

ORIG_HEAD is a special ref that Git saves before dangerous operations (merge, rebase, reset). It points to where your branch was before the operation.

If you already pushed: you must coordinate with the team to recover. This is much harder.

Team recovery steps:

  • 1) Communicate the problem — tell everyone not to pull
  • 2) Find the correct old commit via git reflog
  • 3) Force push the correct history: git push --force-with-lease origin main
  • 4) All teammates must run git fetch then git reset --hard origin/main

Prevention is better than cure: use branch protection rules that disable force pushes on shared branches.

# Scenario: You accidentally rebased main
git rebase feature  # OOPS! Should not have rebased main

# Step 1: Undo immediately (if you haven't pushed)
git reset --hard ORIG_HEAD
# ORIG_HEAD points to main's tip before the rebase
# Main is now restored to its original state!

# Step 2: If you already pushed the rebased main
# Find the old main tip
git reflog
# abc1234 HEAD@{2}: rebase: checkout feature
# def5678 HEAD@{3}: commit: real main commit

# Step 3: Reset and force push
git reset --hard def5678
git push --force-with-lease origin main

# Step 4: Teammates must reset their local main
git fetch origin
git reset --hard origin/main
# WARNING: any local commits on main must be cherry-picked back

# Prevention: Set branch protection on GitHub
# Settings → Branches → Rule: main
# ✅ Do not allow force pushes
ORIG_HEAD is Git's emergency undo button. Before any rebase, merge, or reset, Git saves the current HEAD to ORIG_HEAD. If something goes wrong, git reset --hard ORIG_HEAD takes you right back to where you were. But ORIG_HEAD only saves ONE level back — if you do two dangerous operations, the first one's ORIG_HEAD is lost. Use git reflog for deeper recovery.

Lo kar liya — Key Points:

  • ✅ NEVER rebase commits that have been pushed to a shared branch (main, develop, release)
  • ✅ Rebase rewrites history — teammates who pulled the old history will have divergent repositories
  • ✅ Do not rebase after PR approval — it invalidates CI results and code review
  • ✅ Only rebase local feature branches that no one else has pulled
  • ✅ git reset --hard ORIG_HEAD undoes a rebase if you haven't pushed yet
  • ✅ If you accidentally push a rebased shared branch, use reflog to find the correct history and coordinate team recovery
  • ✅ Prevent accidents with branch protection rules that disable force pushes
Course Search
Search across all chapters & stages
📖

Search the course

Type any topic — branching, stash, rebase, hooks — and jump straight to that chapter.

merge branchesgit stashundo commitrebase