Force Push

Updated

October 30, 2026

Force Push Dangers

After this page you can update a remote after a rebase without clobbering someone else’s commits.

Why push refuses

You rebased feat/ping-json. Local hashes are new. The remote still has the old chain. A plain git push is a non-fast-forward and Git rejects it.

 origin/feat    A ← B ← C ← D ← E
 local feat     A ← B ← C ← G ← D' ← E'     (rebased onto new main)

 plain push     rejected (not a fast-forward)
 --force-with-lease
   if origin still at E  →  origin becomes E'
   if teammate added F   →  lease fails, fetch first

--force-with-lease

git push --force-with-lease origin feat/ping-json

Git checks that the remote ref still points at what you last fetched. If a teammate pushed in the meantime, the lease fails and you fetch again. That is the default force this book uses.

--force

git push --force origin feat/ping-json

Overwrites the remote ref even if it moved. Use on a branch only you own, and only when you meant to throw away the remote’s extra commits. Never a habit on main.

main

Do not force-push main on a shared remote. Revert instead (chapter 10). Forges often deny force on the default branch (chapter 31).

Recover if you force-pushed by mistake

The old commits may still be on your laptop (git reflog) or another clone. Push them back:

git reflog
git push --force-with-lease origin <old-hash>:main   # only if you own this recovery

That is an emergency. Coordinate on chat first.

Lease plus fetch

Always:

git fetch origin
git log --oneline --graph --decorate HEAD origin/feat/ping-json
git push --force-with-lease

Look at the graph. Then push.