You should never use git push --force
. Instead you should always use
git push --force-with-lease
force vs force-with-lease
git push --force
overwrites the remote branch, while git push --force-with-lease
only overwrites the remote branch if your local copy is aware of all of the commits on the remote branch. This difference makes it significantly more difficult to destroy someone else’s changes on the project.
Scenario | git push |
git push --force |
git push --force-with-lease |
---|---|---|---|
New commits on local branch | works | works | works |
New commit on remote branch added by another user | FAILS | works | FAILS |
Commit from remote branch is modified on local branch | FAILS | works | works |
The failure of git push --force-with-lease
when there are new commits on the remote branch added by another user is a far better default behavior than overwriting the other user’s commits.
When git push succeeds
The git push
command expects you to push new commits on top of the already existing commits on the remote branch.
Imagine the commits for your local master
branch and the remote server origin/master
branch look something like this
master origin/master (remote)
dg34mp
cem32k cem32k
b4d2o1 b4d2o1
abc123 abc123
(If viewing your Git branch as a list of commits like this seems unfamiliar, I suggest checking out my post on How to Improve Git Log).
Then you use
git push
and the remote server origin/master
is brought up-to-date.
master origin/master (remote)
dg34mp dg34mp
cem32k cem32k
b4d2o1 b4d2o1
abc123 abc123
When git push fails
The git push
command fails when the commits on your remote branch do not match the commits on your local branch.
Someone Else Added a Commit
In this case, while you were creating your new commit (dg34mp
) on your local branch, someone else added their own commit (zyx911
) to the remote branch.
master origin/master (remote)
dg34mp zyx911
cem32k cem32k
b4d2o1 b4d2o1
abc123 abc123
Using git push
, Git recognizes the remote contains a commit you don’t have in your local copy (zyx911
) and returns an error message
error: failed to push some refs
If you were to use git push --force
, you would overwrite the remote origin/master
branch and destroy zyx911
. Destroying someone else’s changes is generally considered a bad thing.
If instead you use git push --force-with-lease
, it will fail, which is what we want in this case. The proper way to resolve this situation, is to pull the new changes (zyx911
) into our local copy. For more information on how to do this, see my Git failed to push some refs post.
You Changed a Commit
When I realize I’ve made a mistake in my last commit (e.g. a typo), I’ll often correct it and amend the commit (with git commit --amend
).
sal-dev origin/sal-dev (remote)
crsc14 crsc14
bu24ox bu24ox
akw82n akw82n
Amending my commit, replaces crsc14
with a new updated commit (kl055q
).
sal-dev origin/sal-dev (remote)
kl055q crsc14
bu24ox bu24ox
akw82n akw82n
Now once again our commits on the remote branch do not match the commits on the local branch.
If we try to git push
, we will get the error message “error: failed to push some refs”.
However, in this situation git push --force-with-lease
will work! It works in this case, because our local install is aware of crsc14
even though it is not part of our current branch.
git please
In order to speedup my workflow, I’ve added a git alias called git please
for git push --force-with-lease
. Someone smarter than I came up with this alias, but I really like the combination of p
(for push) + lease
, as well as please
being a polite request to force push.
You can add this alias to your git install by running the following from the command line.
git config --global alias.please "push --force-with-lease"
Leave a Reply