Force-Push Recovery
Course 2, Chapter 9 introduced why force-push is dangerous; Course 3, Chapter 3 covered recovering your own lost commits via the reflog. This chapter combines both into the genuinely hard version: a history rewrite has already gone out to a shared branch, multiple people have already pulled the bad version, and recovery now needs coordination, not just a local fix.
The Scenario
Step 1: Stop — Don't Let Anyone Push Yet
The single most important first action is communication, not commands. A quick message — "I just rewrote history on feature/checkout, please don't push anything to it until I say it's safe" — prevents the situation from getting worse while you sort out the recovery plan.
Step 2: Establish What Everyone Actually Has
Step 3: Recovering Each Person onto the New History
Assuming the decision is to keep your rewritten history and bring everyone else's unpushed work onto it — for each affected teammate, individually:
$ git log --oneline origin/feature/checkout..HEAD
4f3e2d1 My genuinely new work, not yet pushed anywhere
$ # Fetch your rewritten history
$ git fetch origin
$ # Cherry-pick just their genuinely new commits onto the new history (Course 2, Ch5)
$ git switch -c feature/checkout-recovered origin/feature/checkout
$ git cherry-pick 4f3e2d1
$ # Verify everything looks right, then this becomes their new feature/checkout
Step 4: If You Need to Recover the OLD History Instead
If the team decides the rewrite itself was the mistake and should be undone entirely — your own reflog (Chapter 3) almost certainly still has the pre-rewrite state, since your local repo's reflog isn't affected by what you pushed.
b2c1d0e HEAD@{6}: commit: Last commit before the rebase
$ # Restore the branch to its pre-rewrite state...
$ git reset --hard b2c1d0e
$ # ...and push it back, undoing your own force-push
$ git push --force-with-lease origin feature/checkout
Preventing the Next One
- Branch protection's "block force pushes" (Course 2/3, Chapter 9/6) on genuinely shared branches removes this entire category of incident as a possibility.
- Reserve interactive rebase and history rewriting (Chapter 2) for branches you're confident are still personal, even if technically pushed somewhere.
- If a shared branch genuinely needs cleanup, communicate first, every time — the actual technical recovery in this chapter is straightforward; the damage comes from skipping the coordination step.
Chapter 9 Quick Reference
- First action: communicate, don't compute — stop anyone else from pushing or "fixing it" before you have a plan
- Establish what everyone has before running any recovery commands — unpushed local work is the most valuable thing in play
- Cherry-pick each person's genuinely new commits onto the corrected history — works regardless of how different the rest of the history now looks
- To undo the rewrite entirely: your own reflog (Ch3), or any teammate's untouched local copy if yours has expired
- git push --force-with-lease (not plain --force) when pushing the restored history back
- Prevention: branch protection blocking force pushes, reserving rewrites for genuinely personal branches, communicating before any history-rewriting operation on shared work
- Next chapter (final, Scenario): full repo migration — splitting/merging repos while preserving history, moving hosts, handling LFS/submodules