How do you safely force-push and what does --force-with-lease do?
Learn how to force-push safely in Git. See how --force-with-lease prevents overwriting teammates' commits, and why fetching first keeps the check reliable.
Expected Interview Answer
You force-push safely by using git push --force-with-lease instead of --force: it overwrites the remote branch only if the remote is still at the commit your local tracking ref expects, so it refuses to clobber work someone else pushed after your last fetch.
A plain --force overwrites the remote branch unconditionally and can silently erase teammates' commits. --force-with-lease adds a safety check by comparing the remote's current tip against your cached remote-tracking ref (your 'lease'); if they differ, the push is rejected. To use it correctly you must fetch before pushing so your lease reflects reality, and avoid background auto-fetches that could refresh the lease and defeat the check. For maximum precision, --force-with-lease=<ref>:<expected-sha> pins the exact commit you expect.
- Prevents overwriting commits pushed by others after your last fetch
- Turns a destructive operation into a conditional, checked one
- Safe way to update history after a rebase or amend
- Gives a clear rejection instead of silent data loss
- Supports pinning an exact expected commit for extra precision
AI Mentor Explanation
A plain force-push is like replacing the official scoresheet with your own copy without checking whether the scorer added runs while you were away — any deliveries they recorded vanish. --force-with-lease is like first confirming the board still shows the exact total you last saw; only if it matches do you swap in your version, so no runs scored in the meantime are wiped out.
Step-by-Step Explanation
Step 1
Understand why you're rewriting history
Force-push is needed after rebase, amend, or squash because the branch's commits no longer descend from the remote's tip.
Step 2
Fetch first
Run git fetch so your remote-tracking ref (the lease) accurately reflects the remote's current tip.
Step 3
Prefer --force-with-lease
git push --force-with-lease overwrites only if the remote is still at your expected commit, rejecting the push otherwise.
Step 4
Read a rejection as a warning
If rejected, someone pushed after your fetch; inspect their commits and integrate before trying again.
Step 5
Pin the exact ref when precise
Use --force-with-lease=main:<sha> to state the exact commit you expect, avoiding stale-lease surprises from auto-fetch.
What Interviewer Expects
- Knowing --force overwrites unconditionally and risks data loss
- Explaining that --force-with-lease checks the remote against your tracking ref
- Understanding you must fetch so the lease is accurate
- Recognizing a rejected push means someone else pushed
- Awareness of the explicit =ref:sha form for precision
Common Mistakes
- Using --force by default and clobbering teammates' commits
- Thinking --force-with-lease never fails
- Not fetching first, so the lease is stale
- Letting background auto-fetch refresh the lease and defeat the safety check
- Force-pushing shared branches like main without team agreement
Best Answer (HR Friendly)
“Force-pushing overwrites the shared branch with your version, which can accidentally delete a teammate's work. The safe way is --force-with-lease, which only overwrites if the server still matches what you last saw — so if someone else pushed in the meantime, Git stops you instead of erasing their changes.”
Code Example
# Rebase your feature branch onto the latest main
git fetch origin
git rebase origin/main
# Refresh the lease so it reflects the true remote tip, then push safely
git fetch origin
git push --force-with-lease origin feature-branch
# If rejected, someone pushed after your fetch - investigate before retrying
git log feature-branch..origin/feature-branch --oneline# Most precise: overwrite only if the remote tip equals this exact SHA
git push --force-with-lease=feature-branch:abc1234 origin feature-branch
# Unsafe - overwrites unconditionally, can erase others' commits (avoid on shared branches)
git push --force origin feature-branchFollow-up Questions
- Why can a background auto-fetch make --force-with-lease unsafe?
- What is the difference between --force and --force-with-lease?
- When would you ever need a plain --force?
- How does rebasing a shared branch create the need to force-push?
- What does the =<ref>:<sha> form of --force-with-lease guarantee?
MCQ Practice
1. What does --force-with-lease check before overwriting the remote?
It compares the remote's current tip to your cached tracking ref (the lease) and rejects the push if they differ.
2. Why must you fetch before using --force-with-lease?
If your tracking ref is stale, the lease check may pass incorrectly; fetching makes the comparison meaningful.
3. What is the main risk of plain git push --force?
--force overwrites the remote branch unconditionally, which can erase teammates' work without warning.
Flash Cards
What does --force-with-lease do? — Overwrites the remote branch only if its tip still matches your remote-tracking ref, preventing silent loss of others' commits.
--force vs --force-with-lease? — --force overwrites unconditionally; --force-with-lease adds a check against your cached remote state and rejects if it changed.
Why fetch before --force-with-lease? — So the lease reflects the remote's real current tip, making the safety comparison meaningful.
When is a force-push needed? — After rewriting history (rebase, amend, squash) because the branch no longer descends from the remote tip.