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.
|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
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
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
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
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 (
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.
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"