Branch Protection Rules Setup for GitHub and GitLab

A random force-push to main or a commit without code review can crash production and cost the team hours of debugging. We configure branch protection rules for GitHub and GitLab to mechanically block such risks. Our team delivers turnkey branch protection with mandatory reviews, force-push bans, and ongoing configuration support.

Our competencies:

Frequently Asked Questions

Latest works

  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1359
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1330
  • B2B Advance company logo design
    B2B Advance company logo design
    776
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1077
  • AIDER company logo development
    AIDER company logo development
    1022
  • CRM development for Chasseurs
    CRM development for Chasseurs
    1113

How We Protect Your Branches: Configuring Branch Protection Rules

Imagine: on a Friday evening, a developer accidentally pushes raw code to main, and production goes down. Figuring out the cause takes 3 hours, and fixing it another half a day. Had branch protection rules been in place, the commit wouldn't have gone through — CI would have failed, and the merge would have been blocked. We've seen such incidents dozens of times across different projects, from startups to enterprise. Each time they cost the team hours of debugging and nerves. Branch Protection Rules are the only mechanical barrier that prevents this. Proper configuration of protected branches reduces force-push incidents to zero and saves up to 80% of team time spent fixing accidental breaks. This article shares practical experience in setting up branch protection for GitHub and GitLab, with real configurations and proven recommendations. Our engineers have configured protection for over 200 repositories over several years.

Why Branch Protection Is Critical?

Without rules, any developer can:

  • Push directly to main — and production breaks.
  • Force-push — lose colleagues' commits.
  • Merge a PR without a single approval — unreviewed code goes into release.

Our engineers configure rules to reduce these risks to zero, while keeping the team from suffering excessive restrictions. According to statistics, teams with protected branches spend 80% less time fixing accidental breaks. The frequency of force-push incidents drops to zero. We guarantee that after our setup, your main will stay clean.

How to Configure Protection in GitHub?

Configuration is in Settings → Branches → Add branch protection rule. Step by step:

  1. Specify the branch pattern (e.g., main or release/*).
  2. Enable "Require a pull request before merging" — direct push is prohibited.
  3. Set "Required approvals" — we recommend 2.
  4. Enable "Require status checks" and specify CI job names (e.g., build, test).
  5. Activate "Require up-to-date branches" and "Require conversation resolution".
  6. Enable "Do not allow bypassing" — even admins must follow the rules.

Below are typical settings for a production branch:

Option Recommendation Explanation
Require a pull request before merging Enabled Direct push banned; PR required
Required approvals 2 At least two approvals
Dismiss stale approvals Enabled Resets approvals on new commits
Require status checks Enabled CI must be green
Require up-to-date branches Enabled Branch must contain latest base changes
Require conversation resolution Enabled All comments must be resolved
Do not allow bypassing Enabled Even admins obey rules

Important: for Require status checks, you must explicitly list the job names (e.g., build, test). Without that, the rule won't work. See GitHub documentation for details.

How to Configure Protection in GitLab?

Configuration in GitLab (Settings → Repository → Protected Branches) is more granular. Steps:

  1. Choose the branch (e.g., main).
  2. Set "Allowed to push and merge" = "No one".
  3. "Allowed to merge" = "Maintainers".
  4. Enable "Code owner approval required".
Branch: main Allowed to push and merge: No one Allowed to merge: Maintainers Code owner approval: Required 

Setting Allow to push = No one ensures that even the repository owner cannot push directly — only through a Merge Request. This enforces discipline better than any code review guidelines.

GitLab also supports Push Rules (Settings → Repository → Push Rules):

  • Reject unsigned commits — only GPG-signed commits
  • Check whether author is a GitLab user — blocks commits from unknown emails
  • Prevent pushing secret files — bans files like .pem, .key, id_rsa
  • Commit message regex — mandatory task ID: ^(PROJ-\d+|Merge branch)

See GitLab documentation for details.

Which Rules Protect Your Branch?

Branch protection rules cover several security layers. The first is mandatory PR and approvals. The second is status checks: CI must be green. The third is restrictions on force push and confidential files. Combining these layers gives protection against 99% of typical errors.

Comparison of GitHub and GitLab

Feature GitHub GitLab
Mandatory PR Require pull request Merge request required
Required approvals Required approvals Approval rules
CI control Require status checks CI must succeed
Force push ban Include administrators No one allowed to push
CODEOWNERS .github/CODEOWNERS File-based, also Code Owner approval

What Is Included in Branch Protection Setup?

  • Audit of current configuration — check existing rules, identify weak points
  • Rule design — tailored to your branching model (GitFlow, Trunk-based, GitHub Flow)
  • Setup on all repositories — including organization-level rules (GitHub Enterprise / GitLab Premium)
  • Documentation — description of rules and recommendations for the team
  • Developer training — how to work with protected branches
  • Support — help with incidents, rule adjustments

Additionally, we can configure CODEOWNERS for automatic reviewer assignment. Example file:

# Global — tech lead * @myorg/tech-leads
# Infrastructure — SRE infrastructure/ @myorg/sre-team *.tf @myorg/sre-team
# Frontend src/components/ @myorg/frontend-team
# Backend src/api/ @myorg/backend-team
Example GitHub configuration
# .github/protected-branches.yml
branch_protection:
  - pattern: main
    require_pr: true
    required_approvals: 2
    dismiss_stale: true
    require_status_checks:
      - build
      - test
    require_up_to_date: true
    require_conversation_resolution: true
    enforce_admins: true
    allow_force_pushes: false
    allow_deletions: false

Force Push: When to Allow, When to Forbid

We always forbid it for main and develop — force-push rewrites history. If someone has already deployed a commit that is later overwritten, hard-to-debug discrepancies arise. For feature branches, you can allow force-push, but only with --force-with-lease (not --force). This command refuses to proceed if the server has commits not present locally. That way you won't lose others' changes.

Timeline and Cost

Configuring branch protection rules for a single repository takes 2-3 hours. With CODEOWNERS, push rules, and documentation — half a day. Organization-level ruleset (applies to all repos) — 1 day. Cost is calculated individually — depends on the number of repositories, complexity of rules, and need for team training. Average time savings after implementation reaches 80% — by eliminating manual rollbacks and downtime. Over several years, we have configured protection for more than 200 repositories — from startups to enterprise clusters. Our engineers have years of experience. We guarantee that the setup will not block development processes — we test every rule on sample repositories.

To get advice on configuring branch protection, contact us — we'll select the optimal rules for your workflow. Order an audit of your current branch protection configuration.