linuxlab.io
Tutorials▾
  • Linux & networking
    File system, processes, TCP/IP, BGP and OSPF
    →
  • Terraform & IaC
    HCL, state, plan/apply on a LocalStack sandbox
    →
  • Git & GitHub
    Object model, plumbing, branching, GitHub Actions
    →
All tutorials →
PricingAboutSign inCreate account
/
Intro
Lessons
Footer
linuxlab-TutorialsPricingAboutPrivacy & cookies
Copyright © 2026 LinuxLab. All rights reserved.
linuxlab.io
Tutorials▾
  • Linux & networking
    File system, processes, TCP/IP, BGP and OSPF
    →
  • Terraform & IaC
    HCL, state, plan/apply on a LocalStack sandbox
    →
  • Git & GitHub
    Object model, plumbing, branching, GitHub Actions
    →
All tutorials →
PricingAboutSign inCreate account
/
  • Introduction
  • Chapters
  • How it works
  • Lessons
  • Knowledge base
  • Interview prep
home/git/how/force-push-lease

how/collaboration

force push: --force vs --force-with-lease

Why --force-with-lease exists, exactly how it protects you from overwriting someone else's commits, and why a background fetch can fool it. Three zones, five scenarios.

git push --force is one of those tools you should not use until you understand what it does. It overwrites the remote history with yours silently, even if someone pushed there after you. One bad push and other people's commits disappear from the shared remote.

git push --force-with-lease is the safe counterpart. It checks that the remote branch is the same one you last saw through git fetch. If it is not, it refuses.

For this to work, Git has three zones, not two:

  • local repo: your clone, with your feat.
  • refs/remotes/origin/feat (also the remote-tracking ref): a local cache of which SHA was on the remote at the last fetch. This is not the remote, it is your idea of the remote.
  • origin · remote: the server itself, the current state.

Press ▶ and watch how these three references diverge and why one of them can betray you.

step 1/5·00 · everything matches, a normal push works
LOCAL REPOтвой клонORIGIN/FEATremote-tracking ref (кэш)ORIGIN · REMOTEреальный серверfeatSHAaaa1111refs/remotes/origin/featSHAaaa1111featSHAaaa1111git push✓ acceptedвсё совпадает - обычный fast-forward push работает, никакого force не нужно

§ steps

  1. The baseline. You just made a commit on feat, you did not rebase, and nobody else pushed to feat.

    local feat              = X
    origin/feat (tracking)  = X
    remote feat             = X

    git push goes as a normal fast-forward: your local moved one commit ahead, the remote is the ancestor. No force is needed here, and no traps.

    This is where all three zones start: local, origin/feat, remote. Next we will watch how they diverge.

recap

What to remember:

  • --force overwrites the remote silently. If, between your last fetch and your push, someone committed to the same branch, their commit disappears with no warning.
  • --force-with-lease takes the SHA from your refs/remotes/origin/feat (what you last saw) and compares it to the real SHA on the remote. If they differ, it refuses with "stale info" and the other person's commit is saved.
  • A background fetch breaks the lease. If your IDE, a watcher, or a parallel terminal managed to fetch without you, refs/remotes/origin/feat silently updated to someone else's fresh SHA. The lease matches the remote, the force goes through, and the other person's commit is overwritten.
  • An explicit SHA in the lease protects you from a silent fetch: git push --force-with-lease=feat:<sha>, where <sha> is the one you actually saw and deliberately decided to overwrite. The comparison is against that SHA, not against the remote-tracking ref.
  • On main/master, force-push must be blocked by branch protection. That is a safety net at the bottom so nobody's stray fingers can reach it.

A rule for your fingers: never --force, always --force-with-lease. It helps to set up an alias:

bash
git config --global alias.pushf 'push --force-with-lease'

§ dig into the knowledge base

  • force-pushforce push - rules and pitfalls
  • pushpush - the normal non-force case
  • fetchfetch - where origin/feat comes from
  • tracking-branchtracking branch - what refs/remotes/... is
  • rebaserebase - the typical reason for a force-push
Footer
linuxlab-
Copyright © 2026 LinuxLab. All rights reserved.
Tutorials
Pricing
About
Privacy & cookies