C.W.K.
Stream
Lesson 05 of 05 · published

Force Push With Lease

~18 min · push, force-with-lease

Level 0Untracked Rookie
0 XP0/47 lessons0/14 achievements
0/100 XP to next level100 XP to go0% complete

force-push, but with a lease

After any history-rewriting operation — amend on a pushed commit, interactive rebase, dropping or squashing pushed commits — your local branch and the remote branch hold different histories for the "same" work. Plain git push is rejected because Git refuses to overwrite history that exists on the server. To complete the rewrite, you have to force-push. Plain --force is the wrong tool. --force-with-lease is the right one.

The difference matters. Plain git push --force overwrites the remote tip with your local tip, no questions asked. If a teammate pushed a commit you did not have, your force-push wipes their commit from the server. git push --force-with-lease includes a check: it remembers the remote tip from your last fetch, and refuses to push if the remote tip has moved since then. Same convenience when nothing surprising happened, an immediate refusal when concurrent work would be lost.

The newer --force-with-lease=<branch>:<sha> form lets you specify exactly which remote SHA you expect, useful in scripts. Git 2.30+ added --force-if-includes as an extra safety: it ensures your local branch was based on the remote tip you are about to overwrite, catching the "I forgot to fetch" case that --force-with-lease alone misses on auto-fetch setups. Use both together for full safety: git push --force-with-lease --force-if-includes.

The discipline that prevents disasters: never type git push --force. Alias it to fail. git config --global alias.pushf 'push --force-with-lease --force-if-includes' gives you git pushf as a safe shortcut, and the muscle memory shifts. Plain --force remains available for the rare scripted case where you really know what you are doing — but it is no longer your default reflex, and the cost of typo errors drops to near zero.

Code

Safe force-push by default·bash
# After local rebase or amend on a pushed commit:
git push --force-with-lease --force-if-includes

# What --force-with-lease checks:
#   The remote tip must be where it was when you last fetched.
#   If teammates pushed concurrently, the push is refused.

# What --force-if-includes adds:
#   Your local branch must be based on the remote tip you are
#   about to overwrite — catches "I forgot to fetch" cases.

# Recommended alias:
git config --global alias.pushf 'push --force-with-lease --force-if-includes'
git pushf
Recovering from a bad force-push·bash
# Teammate force-pushed and overwrote your work?
# Their reflog might have your tip. Or you can use yours:

git reflog                       # find the pre-force-push tip
git reset --hard HEAD@{N}        # restore your local

# Then either:
git push --force-with-lease      # republish (after coordinating!)
# or:
git switch -c rescue HEAD@{N}    # save it as a separate branch
git push -u origin rescue

External links

Exercise

On a personal branch, push two commits, then git rebase -i to squash them into one and try plain git push — read the rejection. Push again with git push --force-with-lease and confirm success. Add the pushf alias from the lesson. From now on, type git pushf instead of git push --force in this exercise and any future one. Note the muscle-memory difference.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.