force overwrites a remote branch with your local branch.

--force-with-lease is a safer option that will not overwrite any work on the remote branch if more commits were added to the remote branch (by another team-member or coworker or what have you). It ensures you do not overwrite someone elses work by force pushing.

I think your general idea surrounding the command is correct. If the remote branch has the same value as the remote branch on your local machine- you will overwrite remote. If it doesn't have the same value- it indicates a change that someone else made to the remote branch while you were working on your code and thus will not overwrite any code. Obviously if there are additional commits in remote then the values won't be the same.

I just think of --force-with-lease as the option to use when I want to make sure I don't overwrite any teammates code. A lot of teams at my company use --force-with-lease as the default option for a fail-safe. Its unnecessary in most circumstances but will save you lots of headache if you happen to overwrite something that another person contributed to remote.

I'm sure you looked at the docs but there might be some more wordy explanation contained in here:

https://git-scm.com/docs/git-push

Answer from chevybow on Stack Overflow
Top answer
1 of 8
1018

force overwrites a remote branch with your local branch.

--force-with-lease is a safer option that will not overwrite any work on the remote branch if more commits were added to the remote branch (by another team-member or coworker or what have you). It ensures you do not overwrite someone elses work by force pushing.

I think your general idea surrounding the command is correct. If the remote branch has the same value as the remote branch on your local machine- you will overwrite remote. If it doesn't have the same value- it indicates a change that someone else made to the remote branch while you were working on your code and thus will not overwrite any code. Obviously if there are additional commits in remote then the values won't be the same.

I just think of --force-with-lease as the option to use when I want to make sure I don't overwrite any teammates code. A lot of teams at my company use --force-with-lease as the default option for a fail-safe. Its unnecessary in most circumstances but will save you lots of headache if you happen to overwrite something that another person contributed to remote.

I'm sure you looked at the docs but there might be some more wordy explanation contained in here:

https://git-scm.com/docs/git-push

2 of 8
168

Looking for an answer drawing from credible and/or official sources.

The "compare and swap" mentioned by torek in the comments and in his other answer is further illustrated by the sources of Git itself.

the latter only pushes to the remote if the remote does not have commits that the local branch doesn't have?

That feature was introduced in this commit (Dec. 2013, Git v1.8.5-rc0)

--force-with-lease will protect all remote refs that are going to be updated by requiring their current value to be the same as some reasonable default, unless otherwise specified;

For now, "some reasonable default" is tentatively defined as "the value of the remote-tracking branch we have for the ref of the remote being updated", and it is an error if we do not have such a remote-tracking branch.

So "lease" means:

"force-with-lease": You assume you took the lease on the ref when you fetched to decide what the rebased history should be, and you can push back only if the lease has not been broken.

"You assume you took the lease on the ref": So "lease" is used to describe a safety mechanism for force pushing changes to a remote repository.

When you fetch from a remote repository, you essentially get the latest state of the repository at that time. Think of this as taking a "snapshot" or a temporary "lease" on the repository's state.
The "lease" implies that you are aware of the repository's state as of the last fetch and are operating under the assumption that this state has not changed since.

When you use git push --force-with-lease, you are telling Git: "I want to force push my changes, but only if the remote repository is in the same state as my last fetch."
In other words, you can push your changes as long as no one else has pushed any updates to the remote repository since your last fetch.
If someone else has introduced changes to the remote repository (thereby "breaking the lease"), the push will be rejected. That helps prevent accidental overwriting of others' work.

The sources still mention "cas" ("compare and swap"):

  • This option was originally called "cas" (for "compare and swap"), the name which nobody liked because it was too technical.
  • The second attempt called it "lockref" (because it is conceptually like pushing after taking a lock) but the word "lock" was hated because it implied that it may reject push by others, which is not the way this option works.
  • This round calls it "force-with-lease".
    You assume you took the lease on the ref when you fetched to decide what the rebased history should be, and you can push back only if the lease has not been broken.

So: "git push --force-with-lease vs. --force"

As I mentioned in "push --force-with-lease by default", Git 2.13 (Q2 2017) confirms that the option --force-with-lease can be ignored if a background process (like the ones you find in an IDE with a Git plugin) runs git fetch origin.
In that case, --force prevails.

As Pavlus adds in the comments:

it is not ignored per se, it is just now you have identical refs for local remote head and remote head, so --force-with-lease will behave correctly -- compare these two, and if in that interval of time between fetch and push, someone updated remote, it won't behave as --force, it will still fail.


Another difference: before Git 2.29 (Q4 2020), pushing a ref whose name contains a non-ASCII character with the "--force-with-lease" option did not work over smart HTTP protocol.
It would work with git push --force.

See commit cd85b44 (21 Jul 2020) by Brian m. Carlson (bk2204).
(Merged by Junio C Hamano -- gitster -- in commit c2796ac, 30 Jul 2020)

remote-curl: make --force-with-lease work with non-ASCII ref names

Reported-by: Frej Bjon
Signed-off-by: brian m. carlson

When we invoke a remote transport helper and pass an option with an argument, we quote the argument as a C-style string if necessary.
This is the case for the cas option, which implements the --force-with-lease command-line flag, when we're passing a non-ASCII refname.

However, the remote curl helper isn't designed to parse such an argument, meaning that if we try to use --force-with-lease with an HTTP push and a non-ASCII refname, we get an error like this:

error: cannot parse expected object name '0000000000000000000000000000000000000000"'  

Note the double quote, which get_oid has reminded us is not valid in an hex object ID.

Even if we had been able to parse it, we would send the wrong data to the server: we'd send an escaped ref, which would not behave as the user wanted and might accidentally result in updating or deleting a ref we hadn't intended.

Since we need to expect a quoted C-style string here, just check if the first argument is a double quote, and if so, unquote it.
Note that if the refname contains a double quote, then we will have double-quoted it already, so there is no ambiguity.

We test for this case only in the smart protocol, since the DAV-based protocol is not capable of handling this capability.
We use UTF-8 because this is nicer in our tests and friendlier to Windows, but the code should work for all non-ASCII refs.

While we're at it, since the name of the option is now well established and isn't going to change, let's inline it instead of using the #define constant.


Git 2.30 (Q1 2021) adds git push --force-if-includes

When a local branch that is based on a remote ref, has been rewound and is to be force pushed on the remote, "--force-if-includes" runs a check that ensures any updates to the remote-tracking ref that may have happened (by push from another repository) in-between the time of the last update to the local branch (via "git pull", for instance) and right before the time of push, have been integrated locally before allowing a forced update.


Does it mean that if I do fetch before pushing, then "force-with-lease" will happily overwrite the remote branch, even with other people's work in it? I wonder how well it plays with automatic fetching many IDEs do.

The --force-with-lease option is designed to protect against overwriting changes in the remote repository that you have not seen. When you use this option, Git checks that the remote branch has not changed since your last fetch. If the remote branch has been updated (e.g., by another collaborator's push), the --force-with-lease push will fail.

Automatic fetching by IDEs can lead to scenarios where you unintentionally overwrite changes made by others without reviewing them. This happens because your local view of the remote branch is kept up-to-date automatically, and --force-with-lease checks against this view.

So I would either deactivate the automatic fetch, or at least review the two branches (the current one, and its remote tracking counterpart) before making any force push (with lease or not).

🌐
Git
git-scm.com › docs › git-push
Git - git-push Documentation
I.e. create a base tag for versions of the upstream code that you’ve seen and are willing to overwrite, then rewrite history, and finally force push changes to master if the remote version is still at base, regardless of what your local remotes/origin/master has been updated to in the background. Alternatively, specifying --force-if-includes as an ancillary option along with --force-with-lease[=<refname>] (i.e., without saying what exact commit the ref on the remote side must be pointing at, or which refs on the remote side are being protected) at the time of "push" will verify if updates from the remote-tracking refs that may have been implicitly updated in the background are integrated locally before allowing a forced update.
Discussions

Difference between git push vs git push --force-with-lease
With just ‘—force’ you don’t even need to know what you are overwriting. With lease the remote needs to be as it was when you last fetched. More on reddit.com
🌐 r/git
7
8
January 15, 2021
Does lazygit use `--force` or `--force-with-lease` while force pushing commit?
But yes, lazygit does use --force-with-lease, and it is strongly recommended that you also turn on git config --global push.useForceIfIncludes true to make it actually safe. More on github.com
🌐 github.com
2
1
How to support push --force-with-lease but not git push --force?
We have the Reject Force Push hook turned on in our Bitbucket server which is a godsend for most situations but it prevents a real need which is rebasing a topic branch that is undergoing code review in a PR. For example you might want to: Interactively rebase, squashing commits, fixing commit me... More on community.atlassian.com
🌐 community.atlassian.com
May 29, 2024
Git push --force-with-lease while working with worktrees
Have you tried to fetch first? I think the error message is telling you that the remote version of the branch isn't where you think it is. More on reddit.com
🌐 r/git
17
4
March 27, 2025
🌐
Medium
medium.com › towardsdev › understanding-the-power-of-git-push-force-with-lease-30f73858e0dc
Understanding The Power of ‘git push — force-with-lease’ | by Daniel Ben Hayoun | Towards Dev
April 5, 2024 - The Git documentation describes force-with-lease as a safer option that will not overwrite the work on the remote branch if more commits were added to it (by another team-mate, for example) since you last fetched.
🌐
Reddit
reddit.com › r/git › difference between git push vs git push --force-with-lease
r/git on Reddit: Difference between git push vs git push --force-with-lease
January 15, 2021 -

I'm reading a few articles on:

--force-with-lease

IFrom my understanding, it will halt the push operation if someone has pushed to the same branch while you were working on it It sounds like a normal git push? What am I missing here?

🌐
Adam Johnson
adamj.eu › tech › 2023 › 10 › 31 › git-force-push-safely
Git: Force push safely with --force-with-lease and --force-if-includes - Adam Johnson
If someone else has pushed new commits to the remote branch, a force push will remove them without any indication! To guard against unintentional commit removals, use the alternative option --force-with-lease.
🌐
Hacker News
news.ycombinator.com › item
How is push origin HEAD --force-with-lease different from normal git push? Can s... | Hacker News
November 10, 2022 - I guess git can’t tell the he difference between “not merged yet” and “don’t want to merge, please destroy” · However, we use vscode, and I rather like auto fetch. But apparently this workflow would destroy something auto fetched that I might not have even noticed
Find elsewhere
🌐
DEV Community
dev.to › ruqaiya_beguwala › day-1230-git-push-force-with-lease-safer-alternative-to-force-5fc
Day 12/30 - git push --force-with-lease – Safer alternative to --force - DEV Community
June 2, 2025 - Unlike --force, which blindly overwrites the remote branch, --force-with-lease checks if the remote branch has changed since you last fetched it. git push --force → Overwrites remote branch no matter what.
🌐
Sarahabd
sarahabd.com › sarah abderemane's website › til › git push force with lease
TIL: Git push force with lease
May 22, 2024 - You can rewrite the history of your commits and then force push. The difference between --force and --force-with-lease is with --force-with-lease will push only if you are not overwriting any work on the remote branch if more commits were added to the remote branch.
🌐
Atlassian
atlassian.com › home › ‘–force considered harmful; understanding git’s –force-with-lease
'-force considered harmful; understanding git's -force-with-lease - Inside Atlassian
June 12, 2024 - Now, unless Bob does a pull from the remote, his local reference to the remote will be out of date. When he goes to push using --force-with-lease, git will check the local ref against the new remote and refuse to force the push.
🌐
Graph AI
graphapp.ai › engineering-glossary › git › git-push---force-with-lease
Git Push --Force-with-Lease: Definition, Examples, and Applications | Graph AI
The 'git push --force-with-lease' command is a Git command that allows you to force push your changes to a remote repository, but with a safety check. The 'force-with-lease' option will only allow the push to proceed if the remote branch is in the state that you expect.
🌐
Thoughtbot
thoughtbot.com › blog › git-push-force-with-lease
Force push with care
July 20, 2023 - My coworker Calle (not in the picture) suggested in our guides that we prefer the flag --force-with-lease over --force to the git push command. This option allows one to force push without the risk of unintentionally overwriting someone else’s work. It will update remote references only if it has the same value as the remote-tracking branch we have locally.
🌐
Safjan
safjan.com › home › note › understanding the differences between git push...
Understanding the Differences Between Git Push Force and Git Push Force-With-Lease
July 13, 2023 - If you need to rebase or squash commits, using git push --force-with-lease is a safer option, as it ensures that you are not overwriting any new commits.
🌐
Atlassian Community
community.atlassian.com › q&a › bitbucket › questions › how to support push --force-with-lease but not git push --force?
How to support push --force-with-lease but not git push --force?
May 29, 2024 - It seems like the client is always sending the old target (i.e. the lease) even when not using `--force-with-lease`. Git probably just fetches the old target from the server just before it sends it back. So, it seems to be impossible, as you have written. At least, I couldn't see a way in the protocol to push changes without sending the old target.
🌐
DataCamp
datacamp.com › tutorial › git-push-force
Git Push Force: How it Works and How to Use it Safely | DataCamp
July 24, 2025 - This command adds a safety check when pushing to a remote branch to avoid unexpected commits. ... Think of --force-with-lease like “asking if the coast is clear before jumping in”. Before it does anything, it makes sure no one else has changed the branch.
🌐
GitHub
docs.github.com › en › repositories › managing-your-repositorys-settings-and-features › managing-repository-settings › managing-the-push-policy-for-your-repository
Managing the push policy for your repository - GitHub Docs
You can limit how many branches and tags can be updated in a single push. People with admin permissions for a repository can manage the push policy for the repository.
🌐
Medium
medium.com › @armand.masseau › stop-breaking-everyones-repo-git-push-force-with-lease-39b17d82aacf
Stop Breaking Everyone’s Repo: git push --force-with-lease | by Armand Masseau | Medium
October 3, 2025 - git push -f = “Trust me, overwrite everything.” ... --force-with-lease is the polite version: it only overwrites the remote branch if no one else has pushed since your last fetch.
🌐
Hendrik Lammers
hendriklammers.com › notes › git-force-with-lease
Git force with lease
May 11, 2020 - Use git --force-with-lease to safely force-push without overwriting others' commits. Safer alternative to --force after rebasing.