• Skip to primary navigation
  • Skip to main content
Sal Ferrarello
  • About Sal Ferrarello
  • Speaking
  • Connect
    Mastodon GitHub Twitter (inactive)
You are here: Home / Draft / How is git push force-with-lease aware of a commit

How is git push force-with-lease aware of a commit

Last updated on January 21, 2019 by Sal Ferrarello

If you’re still using git push --force (or git push -f), I hope you’ll read my post Never use git push force.

If you’re using git push --force-with-lease (or using the git please alias), git will only force push changes if your local copy is aware of all of the commits on the remote branch but how is git “aware” of the commits.

Someone Else Pushed a Commit

In the following example, while you were creating commit dg34mp on your local branch someone else posted a new commit (zyx911) on the remote origin/master branch.

master     origin/master (remote)

dg34mp     zyx911
cem32k     cem32k
b4d2o1     b4d2o1
abc123     abc123

When you try to git push, you’ll get the error

error: failed to push some refs

Even if you try git push --force-with-lease, the operation will fail and you’ll get the same error message.

You Modified a Commit

On the other hand, if you have a local copy

sal-dev    origin/sal-dev (remote)

crsc14     crsc14
bu24ox     bu24ox
akw82n     akw82n

and you modify your commit, replacing crsc14 with a new updated commit (kl055q).

sal-dev    origin/sal-dev (remote)

kl055q     crsc14
bu24ox     bu24ox
akw82n     akw82n

git push will still fail, but git push --force-with-lease will work!

The Local Copy of Your Remote Branch

The secret to git push --force-with-lease is your local install includes a copy of the remote branch. When deciding whether or not to force push, git push --force-with-lease checks both the current branch and the local copy of the remote branch when looking for commits that match those on the remote.

Let’s look at these two scenarios again and include our local copy of the remote branch.

You Modified a Commit

Initially, all three branches were in sync.

sal-dev    origin/sal-dev (local)  origin/sal-dev (remote)

crsc14     crsc14                   crsc14
bu24ox     bu24ox                   bu24ox
akw82n     akw82n                   akw82n

but when we modified our commit, replacing crsc14 with a new updated commit (kl055q)

sal-dev    origin/sal-dev (local)  origin/sal-dev (remote)

kl055q     crsc14                   crsc14
bu24ox     bu24ox                   bu24ox
akw82n     akw82n                   akw82n

our local copy of origin/sal-dev was still aware of crsc14, so git push --force-with-lease worked.

Someone Else Pushed a Commit

Initially, all three branches are in sync.

master     origin/master (local)  origin/master (remote)

cem32k     cem32k                 cem32k
b4d2o1     b4d2o1                 b4d2o1
abc123     abc123                 abc123

When we add a new commit (dg34mp) and during the same timeframe someone else adds a new commit to the remote (zyx911), we become out of sync.

master     origin/master (local)  origin/master (remote)

dg34mp                            zyx911
cem32k     cem32k                 cem32k
b4d2o1     b4d2o1                 b4d2o1
abc123     abc123                 abc123

Now our local copy is unaware of commit zyx911 because it does not appear in any of our local branches (neither master nor our local origin/master), therefore git push --force-with-lease will fail.

The correct way to resolve this situation is not to use --force nor --force-with-lease, instead you should pull in the changes from the remote origin/master – see my Git failed to push some refs post.

Sal Ferrarello
Sal Ferrarello (@salcode)
Sal is a PHP developer with a focus on the WordPress platform. He is a conference speaker with a background including Piano Player, Radio DJ, Magician/Juggler, Beach Photographer, and High School Math Teacher. Sal can be found professionally at WebDevStudios, where he works as a senior backend engineer.

Share this post:

Share on TwitterShare on FacebookShare on LinkedInShare on EmailShare on Reddit
Warning! This is a draft, not a finalized post. See full draft disclosure.

Filed Under: Dev Tips, Draft Tagged With: Git

Reader Interactions

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Copyright © 2023 · Bootstrap4 Genesis on Genesis Framework · WordPress · Log in