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.