Is there a way to configure git repository to reject 'git push --force'?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Yes. You can prevent force pushes, but the enforcement has to happen on the remote side, not in each developer's local Git config. A local alias or hook can be bypassed instantly. The real controls are branch protection on hosted platforms or server-side hooks on repositories you administer directly. The rule you are trying to enforce is simple: reject non-fast-forward updates on protected refs.
Understand What Force Push Actually Changes
A normal push moves a branch tip forward. A force push allows the remote branch to be rewritten to a commit that is not a descendant of the old tip.
That is why force push is dangerous in shared branches:
- It can discard commits from other people.
- It can rewrite published history.
- It can break open pull requests or deployment assumptions.
What you want to reject is not literally the --force flag. What you want to reject is the non-fast-forward update that --force enables.
Use Branch Protection on Hosted Git Platforms
If the repository is on GitHub, GitLab, Bitbucket, or a similar platform, the cleanest answer is branch protection. Protect main, master, release branches, or any long-lived shared branch and disable force pushes there.
This approach is better than custom scripting when the platform already supports it because:
- It is centralized.
- It is visible in the repository settings.
- It usually supports exceptions for admins or maintainers if needed.
In hosted environments, branch protection is normally the correct first answer.
Use a Server-Side Hook on Bare Repositories
If you manage the Git server yourself, reject non-fast-forward updates with a pre-receive hook in the bare repository.
Example hooks/pre-receive:
Make it executable:
Now pushes that rewrite main or master will be rejected even if the client uses git push --force.
Protect Only the Right Branches
Not every branch needs the same rule. Many teams allow force pushes on short-lived feature branches but reject them on shared branches.
That is why the hook example checks specific refs:
refs/heads/mainrefs/heads/master- release branches if desired
This keeps history protection strict where collaboration depends on it without making private branch cleanup impossible.
Do Not Rely on Client-Side Hooks
You can add a client-side pre-push hook that warns or blocks a force push, but it is only advisory because each developer controls their own machine. Any policy that truly matters must be enforced by the remote repository.
Client-side safeguards are fine for ergonomics. They are not a security boundary or collaboration guarantee.
Consider --force-with-lease as a Different Policy
Some teams do not want to ban force pushes entirely. They want to ban unsafe force pushes while allowing careful history rewrites on non-shared branches. In those cases, the cultural rule may be:
- Never force push to protected branches.
- Use
--force-with-leaseinstead of raw--forceon personal branches.
That is a workflow policy, not the same thing as remote rejection, but it is worth distinguishing.
Test the Rule Before Trusting It
After configuring protection or hooks, verify it with a safe test repository:
- Create a branch.
- Push normally.
- Rewrite history locally.
- Attempt the force push.
If the push is still accepted, the hook or platform rule is not protecting the ref you think it is.
Common Pitfalls
- Trying to solve the problem with local Git configuration instead of remote-side enforcement.
- Blocking only the literal
--forceflag mentally instead of focusing on non-fast-forward updates. - Applying the rule to every branch and making normal feature-branch cleanup needlessly painful.
- Installing a server-side hook but forgetting to make it executable.
- Assuming hosted Git platforms require custom scripting when built-in branch protection already exists.
Summary
- Yes, a repository can be configured to reject force pushes, but the enforcement must be on the remote side.
- Use branch protection on hosted Git platforms whenever possible.
- On self-managed bare repositories, reject non-fast-forward updates with a server-side hook.
- Protect shared branches selectively rather than applying one rule to every ref.
- Treat client-side hooks as convenience only, not as policy enforcement.

