Introduction
Force-pushing in Git (git push --force
) is a powerful but dangerous command. It overwrites remote changes without checking if others have pushed new commits, which can lead to lost work.
Fortunately, Git provides a safer alternative: git push --force-with-lease
. This command ensures you don't accidentally overwrite someone else's changes while still allowing you to rewrite history when needed.
In this guide, we'll explore how --force-with-lease
works, when to use it, and best practices for avoiding mistakes.
How --force-with-lease
Works
Unlike --force
, which blindly overwrites the remote branch, --force-with-lease
checks if the remote branch has changed since you last fetched it.
Key Difference:
git push --force
→ Overwrites remote branch no matter what.git push --force-with-lease
→ Only overwrites if the remote branch hasn't been updated by someone else.
This prevents accidental overwrites of teammates' work.
Example: When to Use --force-with-lease
Scenario:
You rebase your local branch and want to push the changes, but you're unsure if someone else has pushed new commits.
Safe Approach:
git fetch origin git rebase origin/main git push --force-with-lease
If someone else pushed changes while you were rebasing, Git will block the force-push and warn you.
Dangerous Approach (Avoid):
git push --force # Could overwrite others' work!
Advanced Use Cases
While --force-with-lease
is commonly used for rebasing and amending commits, it has several advanced applications that improve safety in complex Git workflows. Here are some powerful (but less obvious) ways to use it.
1. Partial Force-Push with Explicit Refs
By default, --force-with-lease
checks the entire remote branch, but you can enforce stricter checks by specifying which ref (commit) you expect to be at the tip.
Example:
git push --force-with-lease=origin/main:expected-ref-here
This ensures you only overwrite the branch if the remote's latest commit matches expected-ref-here
.
Use Case:
- You're collaborating on a feature branch and want to ensure no unseen commits exist before force-pushing.
2. Scripting Safe Force-Pushes in CI/CD
In automated pipelines, blindly using --force
can break deployments. --force-with-lease
adds a safety check.
Example (GitHub Actions / CI):
- name: Force-push safely run: | git fetch origin git push --force-with-lease origin "$BRANCH_NAME"
Why?
Prevents race conditions where another job might have updated the branch.
Useful for automated doc updates, regenerated lockfiles, or squashed CI commits.
3. Recovering from a Botched Merge
If you accidentally merged a wrong branch and want to rewind the remote, --force-with-lease
ensures no new commits appeared since your last fetch.
Steps:
git fetch origin git reset --hard origin/main~1 # Undo last merge locally git push --force-with-lease # Only works if remote is unchanged
Safety Net:
If someone else pushed after your merge, Git rejects the push.
4. Atomic Branch Updates with Lease Checks
Combine --force-with-lease
with --atomic
(Git 2.30+) to push multiple refs safely, ensuring all succeed or none do.
Example:
git push --atomic --force-with-lease origin branch1 branch2
Use Case:
- Synchronizing related branches (e.g.,
main
and adev
branch) without partial updates.
5. Protecting Against Stale Local Refs
If your local repo is outdated (e.g., due to a missed git fetch
), --force-with-lease
still checks the actual remote state, not just your local cache.
How It Helps:
Even if your
origin/main
is stale, Git contacts the remote server to verify the latest commit.Safer than
--force
, which relies only on your local refs.
Pro Tips
Tip 1: Combine with --dry-run
Test force-pushes safely first:
git push --force-with-lease --dry-run
Tip 2: Lease with Specific Refs for Automation
In scripts, hardcode the expected commit:
git push --force-with-lease=origin/feature-branch:abcd1234
Tip 3: Bypass Lease Checks (When Absolutely Needed)
Use --force-if-includes
(Git 2.30+) to verify your local branch includes the remote tip before pushing:
git push --force-if-include
When Not to Use --force-with-lease
Shared branches: Avoid force-pushing to
main
/master
entirely.After a
git pull --rebase
: Fetch explicitly first, aspull
can obscure remote changes.
Conclusion
--force-with-lease
isn't just for rebasing---it's a precision tool for advanced workflows like CI/CD, multi-ref pushes, and recovery scenarios. By leveraging its ref-checking capabilities, you can enforce stricter safety rules than --force
while maintaining flexibility.
Key Takeaway:
Use
--force-with-lease
whenever you'd use--force
, unless you intentionally want to ignore remote changes.
Up next: git pull --rebase
– Keep history linear when pulling changes
Daily advance GIT tips in your inbox—worth starting? Respond to my poll here🚀
For more useful and innovative tips and tricks, Let's connect on Medium
Top comments (0)