Force Push (--force, --force-with-lease)
A force push overrides Git’s normal protection that says “don’t replace remote history with something different.” After a rebase, an amend, or a reset, your local branch no longer fast-forwards onto the remote — it’s diverged, because you rewrote commits. To make the remote match, you force push. This is fine for personal branches and catastrophic for shared ones.
The two flavours
--force(or-f) — overwrite the remote no matter what. Dangerous: can erase teammates’ commits.--force-with-lease— overwrite only if the remote is in the state you expect (the same as what you last fetched). Safe.
When you need to force push
After a
git rebasethat rewrote commits already pushed.After
git commit --amendon a commit already pushed.After
git reset --hard <older-commit>to discard pushed work.After
git filter-repoto scrub history.
Plain --force
git push --force origin feature-x # Replaces origin/feature-x with your local feature-x, no questions asked
--force-with-lease
git push --force-with-lease origin feature-x # If origin/feature-x is the same commit you last fetched: replace it. # If someone else pushed since your last fetch: refuse, telling you to fetch first.
How --force-with-lease protects you
The check
On your machine, Git remembers: origin/feature-x points to commit ABC (last seen at fetch time) You're about to push your local feature-x → tip = XYZ Push goes out: "Replace remote feature-x with XYZ, but only if it's currently at ABC." If teammate pushed in the meantime (remote is now at QRS): Server: 'no, remote is at QRS, not ABC' → refuses. If remote is still at ABC: Server replaces ABC with XYZ. Safe.
Setting an alias
Make safe the default
git config --global alias.pushf "push --force-with-lease" # Then: git pushf # Never accidentally type --force again
The golden rule (worth repeating)
— Your personal feature branches (no one else has them).
— Branches your team explicitly agreed to rewrite.
Force push is **never** acceptable on:
— `main`, `master`, `develop`.
— Release branches others may have based work on.
— Any branch under active use by multiple people.
Branch protection
Hosting platforms can block force pushes. On GitHub: Settings → Branches → Branch protection rules → Disallow force pushes. Set this for every branch you really do not want rewritten.
Recovering from a bad force-push
If a teammate force-pushed and lost your work
# Their reflog still has the pre-force state
git reflog
# d4b1e0c HEAD@{1}: commit: My lost work
# Push it back as a recovery branch
git push origin d4b1e0c:refs/heads/recovered-workIf YOU force-pushed and want to undo
# Find the previous remote commit in your reflog or via git log origin/branch git reflog show origin/feature-x # if your local origin/x still has the old commit # Reset origin to the old commit git push --force-with-lease origin <old-sha>:feature-x
Pushing tags forcefully
Replacing an existing tag (use sparingly)
git tag -f v1.0 git push --force origin v1.0 # Or in one go: git push --force origin refs/tags/v1.0
git push --force-with-lease (or your pushf alias). Never type plain --force again unless you really know why.