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/kb/Remote repositories/force-push

kb/remote ── Remote repositories ── intermediate

Force push

`git push --force` overwrites the remote history with yours. `git push --force-with-lease` does the same, but refuses if someone pushed there after your last fetch. Always use `--force-with-lease`.

view as markdownaka: git-push-force, force-with-lease

A normal push requires fast-forward: the remote branch must be an ancestor of your local branch. This protects against accidentally losing someone else's commits.

Sometimes you need to bypass that protection. After a local rebase, amend, or interactive rebase (interactive-rebase) the commit SHAs have changed, and a normal push refuses:

! [rejected]  feat -> feat (non-fast-forward)

That is where force push comes in.

--force: blunt and dangerous

bash
git push --force origin feat

This tells the remote: "forget what you had, take exactly my history." If someone else pushed a commit between your last fetch and your push, their commit disappears. You will not notice right away: their clone still has it, but it is gone from the shared remote.

That is the classic "someone force-pushed and broke things" disaster in team work.

--force-with-lease: the safe version

bash
git push --force-with-lease origin feat

This tells the remote: "overwrite the branch, but only if its current SHA equals what I last saw via fetch." If the SHA differs, someone pushed after you and the force is cancelled.

! [rejected]  feat -> feat (stale info)

In that case: run git fetch, inspect what came in, decide what to do (usually rebase your commits on top of the new ones), then repeat force-with-lease.

Rule: never --force, always --force-with-lease. Set an alias so your fingers go to the right place automatically:

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

For an even more explicit check, pass the SHA you expect:

bash
git push --force-with-lease=feat:abc123 origin feat

When force push is appropriate

  • After rebasing your feature branch. This is the standard scenario.
  • After amending the last commit on a pushed feature branch.
  • After interactive rebase to clean up history before a PR.

All three apply only to branches that you alone are working on. On main, master, or develop, force push is blocked by branch protection rules on the forge.

When force push is not the answer

  • "I pushed with a typo in the commit message." Usually easier to leave it, or fix it with a new commit.
  • "I want to remove a secret from history." Force push alone is not enough. See git-filter-repo, and rotate the secret regardless.
  • "I could not figure out the merge." No. Do the merge or rebase properly.

Branch protection: the safety net

On GitHub/GitLab, protected branches (main, master, release/*) can have:

  • Force push blocked.
  • Direct push blocked (only through a PR).
  • Required green CI and approvals.

This is a safeguard against human error. Enable it on main always, even in small teams.

Pitfalls

  • A background fetch can fool --force-with-lease. Without an explicit SHA, the lease compares against your remote-tracking ref (refs/remotes/origin/feat). Normally "fetched long ago" works in your favor: the lease sees an old SHA that does not match the real remote, and the push is rejected with stale info. The dangerous case is when something fetches on your behalf (an IDE, a file watcher, a parallel terminal): the remote-tracking ref silently updates to the new foreign SHA, the lease matches, the force goes through, and their commits are gone. The fix is an explicit SHA: git push --force-with-lease=feat:<sha>, where <sha> is what you personally saw via git fetch and consciously decided to overwrite.
  • Some forges keep reflog for 30+ days. If someone was accidentally overwritten, the SHA can usually be recovered from the forge reflog or from a colleague's local clone.
  • Force push breaks stacked PRs. If someone rebased on top of your branch, a force push forces them to rebase again. In a stacked workflow this is normal, but give a heads-up first.

§ команды

bash
git push --force-with-lease

Safe force: refuses if the remote has moved ahead

bash
git push --force

Blunt force: silently overwrites others' commits. AVOID

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

Alias so your fingers go to the right place

bash
git fetch && git push --force-with-lease

Fresh lease before forcing

§ см. также

  • pushgit pushSends local commits to a remote repository and updates the branch there. If the remote received commits from someone else after your last pull, push will refuse until you synchronize.
  • rebasegit rebaseRewrites the commits of a branch so they descend from a different commit. Each commit gets a new SHA; history becomes linear. Safe only on branches that no one else has seen.
  • interactive-rebaseInteractive rebase`git rebase -i <base>` opens an editor with the list of commits from `<base>` to HEAD, where you can rename, combine, delete, and reorder them. It is the primary tool for cleaning up local history.
Footer
linuxlab-
Copyright © 2026 LinuxLab. All rights reserved.
Tutorials
Pricing
About
Privacy & cookies