Git Force Push, the Safe Way

2 min read
TL;DR
  • Use --force-with-lease instead of --force to avoid overwriting teammates' commits
  • --force-with-lease only allows push if the remote matches the last fetched state
  • Use --force-if-includes together to also defend against fetch-only scenarios
  • Register git pushf as an alias for convenience and safety
Cover

TL;DR

Use --force-with-lease instead of --force and you'll never accidentally blow away a teammate's commit. Set up one alias and you're done.

Why Force Push is Needed

After rebase or commit --amend, your local history diverges from the remote. Normal push is rejected, so you need force push. This is where the choice matters.

--force vs --force-with-lease

--force — Unconditionally overwrites the remote branch. If a teammate pushed commits in between, they disappear without warning.

--force-with-lease — Only allows push if the remote matches the state from your last fetch. If someone pushed in between, it's rejected.

I use --force-with-lease regularly, and when I ask colleagues about it, surprisingly few use this option. I've personally been saved by this command several times. Since you never know when you might make a mistake, it's good to make it a habit.

The Trap of --force-with-lease and --force-if-includes

There's one trap with --force-with-lease. If you run git fetch first, your local ref gets updated and the protection is nullified. This is especially important in environments with background auto-fetch like VS Code.

Git 2.30 added --force-if-includes which, when used together, defends against this trap too. It rejects the push if there are commits that were fetched but not actually integrated into your branch.

Practical Alias Setup

git config --global alias.pushf 'push --force-with-lease --force-if-includes'

Then use git pushf origin feature-branch.

Conclusion

There's almost no reason to use --force. Set up one alias and you get shorter typing plus eliminate the risk of destroying teammates' commits.

Refs