Branch Protection

Enforce quality gates and access controls on critical branches.

What Is Branch Protection?

Branch protection prevents unauthorized or unreviewed changes from reaching important branches. Without protection, anyone with push access can commit directly to a branch, bypassing code review, CI checks, and team approval processes. Branch protection rules let you require that changes go through pull requests, pass automated checks, and receive reviewer approval before they can be merged.

Protection rules are especially important for branches that represent production-ready code, release candidates, or shared integration points. A single misconfigured branch can lead to broken builds, untested code reaching production, or changes that nobody reviewed.

How Rules Work

Each branch protection rule consists of a branch pattern and a set of requirements. The branch pattern determines which branches the rule applies to, and the requirements define what conditions must be met before changes can land on those branches.

Branch patterns use glob syntax. A pattern of main matches only the main branch. A pattern of release/* matches all branches under the release prefix, such as release/1.0, release/2.0, and so on. You can create multiple rules with different patterns to apply different protection levels to different branches.

Rules are evaluated at two points: when someone pushes directly to a protected branch, and when someone attempts to merge a pull request into a protected branch. Both pathways enforce the same rules.

Protection Options

Each rule can enable any combination of the following protections:

Require Pull Request

When enabled, direct pushes to the protected branch are rejected. All changes must come through a pull request. This is the foundation of most branch protection setups — it ensures that every change is visible, reviewable, and tracked.

Required Approvals

Sets the minimum number of reviewer approvals a pull request must receive before it can be merged. For example, setting this to two means at least two different reviewers must submit an "Approved" verdict. The PR author's own approval does not count toward this threshold.

Dismiss Stale Reviews

When the PR author pushes new commits after a review has been submitted, this option automatically invalidates previous approvals. Reviewers must re-review the updated code before the PR can be merged. This prevents a scenario where a reviewer approves version one of a change, the author makes significant modifications, and the PR is merged without anyone reviewing those modifications.

Require Code Owner Review

Requires that at least one designated code owner for the affected files approves the pull request. Code owners are team members who are responsible for specific areas of the codebase. This ensures that changes to critical files are reviewed by the people who know those files best.

Required Status Checks

Specifies CI/CD pipeline checks that must pass before a pull request can be merged. For example, you might require that the build succeeds, all tests pass, and linting produces no errors. If any required status check fails, the merge button is blocked until the issues are resolved and the checks pass on a subsequent run.

Status checks are reported by CI/CD Pipelines or external systems via webhooks. You select which specific checks are required from the list of checks that have previously run against the repository.

Require Linear History

When enabled, only merge strategies that produce a linear history are allowed — merge commits are rejected. This means pull requests must use squash, rebase, or fast-forward merge strategies. A linear history is easier to bisect when tracking down bugs and produces a cleaner commit log.

Allow or Deny Force Push

Controls whether force pushes are permitted to the protected branch. Force pushes rewrite history, which can cause problems for anyone who has already pulled the branch. For shared branches like main, force pushes should almost always be denied. You might allow them for specific release branches during the preparation process, but this should be the exception rather than the rule.

Allow or Deny Branch Deletion

Controls whether the protected branch can be deleted. For permanent branches like main or develop, this should be denied. For branches matched by a pattern like release/*, you might allow deletion so old release branches can be cleaned up after they are no longer needed.

Restrict Push Access

Limits who can push to the protected branch, even through merged pull requests. You can specify individual users or teams who are authorized. Everyone else is blocked. This is useful when you want to ensure that only senior engineers or a release team can land changes on a production branch.

Common Protection Patterns

While every team's needs are different, there are several common configurations that serve as good starting points:

Protecting the Main Branch

The main branch typically represents production-ready code. A solid protection configuration includes:

  • Require pull request — no direct pushes.
  • Require at least one approval (two for larger teams).
  • Dismiss stale reviews on new pushes.
  • Require all CI status checks to pass.
  • Deny force push.
  • Deny branch deletion.
Start with these protections on your main branch from day one. It is much easier to establish good habits early than to retrofit them after the team has been pushing directly to main for months.

Protecting Release Branches

Release branches (matched by a pattern like release/*) often need stricter controls because they represent code that is about to ship:

  • Require pull request.
  • Require at least two approvals.
  • Require code owner review for critical files.
  • Require all CI status checks to pass.
  • Require linear history for clean release logs.
  • Deny force push.
  • Allow branch deletion (so old release branches can be cleaned up).

Lightweight Protection for Development Branches

Shared development or integration branches might use lighter protection to keep velocity high while still preventing accidents:

  • Require pull request.
  • Require at least one approval.
  • Require CI status checks to pass.
  • Deny force push.

When Rules Are Enforced

Branch protection rules are enforced at two points:

  • At push time. When someone pushes commits directly to a protected branch (not through a pull request), the server checks whether direct pushes are allowed and whether the pusher is authorized. If the rules require a pull request, the push is rejected.
  • At merge time. When someone attempts to merge a pull request into a protected branch, the server checks all applicable rules — approval count, status checks, code owner review, linear history, and push access restrictions. If any requirement is not met, the merge is blocked.
Branch protection rules apply to everyone, including repository administrators. There is no implicit bypass for admin users. If you need an emergency bypass mechanism, plan for it explicitly by configuring your rules accordingly.