DEV Community

Cover image for Branch Protection Rules vs Rulesets: The Right Way to Protect Your Git Repository
Piyush Gaikwad
Piyush Gaikwad

Posted on

Branch Protection Rules vs Rulesets: The Right Way to Protect Your Git Repository

Do you need a lot of manual clicking every time a new branch is created or a repository rule needs to be enforced 🧐? That's usually a sign that traditional Branch Protection Rules are doing more work than they were designed for.

If you’ve worked on a repository with more than a handful of branches, you’ve probably felt it:

  • duplicated branch protection rules
  • subtle inconsistencies between main, release/, and hotfix/
  • accidental gaps in enforcement
  • configuration drift no one notices until production breaks

With Branch Protection Rules:
✅ You can protect main or release/*
✅ You can enforce PR-based workflows
❌ You cannot prevent unstructured branch names from being created
❌ You cannot enforce naming conventions at branch creation time

Branch Protection Rules operate after a branch exists.

As teams scale, enforcing consistent policies across branches, tags, and repositories becomes increasingly manual and error-prone. This is where Rulesets come in—shifting governance from per-branch configuration to centralized, reusable policies that apply automatically as your repository evolves.

Rulesets were designed to solve these below gaps:

  1. Centralized and reusable Rules:
  2. With branch protection, rules live at the repository level and are often duplicated across projects. Rulesets enable centralized governance, allowing organizations to define consistent policies that can be reused across repositories. This is especially valuable for platform teams managing standards at scale.

  3. Coverage beyond branches:
  4. Branch protection rules apply only to branches. Rulesets extend embed governance to Tags, Multiple branch patterns, and Repository-wide events.
    This makes rulesets suitable for release processes, versioned tagging strategies, and broader repository controls that branch protection cannot address.

  5. No need for hooks enforcement for branch name rules
  6. With rulesets, branch naming policies can be enforced natively at the repository level, eliminating the need for client-side Git hooks or custom validation scripts.

  7. Reduced operational overhead
  8. By eliminating repetitive configuration and manual updates, rulesets reduce the operational burden on maintainers. Policies continue to apply automatically as new branches or tags are created, ensuring protection is not accidentally bypassed.


Now, Let's explore on how the ruleset can go beyond branch protection rules and help in enforcing the creation of unstructured branch names 🤩

Let’s say you want to implement an orchestrated branching workflow, where different types of branches follow different rules before they are created, not after.
In many organizations, feature branches, hotfix branches, and release branches each serve a distinct purpose and therefore require different validation, checks, or governance policies. Branch Protection Rules cannot model this kind of workflow because they apply only once a branch already exists and are limited to protecting a fixed set of branches.

With rulesets, you can define multiple policies, each targeting a specific branch pattern, and enforce them at creation time.

For example, you might require:

  • feature/* : branches to pass basic CI checks,
  • hotspot/* : branches to require additional approvals or stricter checks,
  • release/*: branches to enforce mandatory reviews and block force pushes entirely.

Each ruleset is evaluated automatically as the branch is created, ensuring that the correct governance model is applied from the very beginning. This allows teams to encode branching strategy directly into the platform, rather than relying on post-creation enforcement or manual discipline.

RULESET VS BRANCH protection rules


Now, Let's explore on how there is no need to maintain a separate server-side hook to prevent unstructured branch names such as hot-spot/fix-check when the requirement is simply to enforce a consistent prefix like hotspot/* 😍.

As teams grow, branch naming conventions tend to drift. What starts as a simple guideline—“please prefix branches correctly”—quickly turns into a mix of inconsistent names created through different tools and workflows.
Common problems include:

  • Developers creating branches like hot-spot/fix-check instead of the intended hotspot/fix-check
  • Missing team or ticket identifiers in branch names
  • Inconsistent naming across CLI, GitHub UI, and automation
  • Relying on documentation or tribal knowledge to enforce standards To address this, teams often introduce custom pre-receive hooks or manual review processes, which add operational overhead and require ongoing maintenance.

Sample pre-receive hooks to prevent pushing forbidden branches or adhere to branch namespace looks like:

#!/bin/bash

FORBIDDEN_BRANCH="refs/heads/forbidden-branch"

while read oldrev newrev refname
do
   if [[ "$refname" =~ ^refs/heads/(master|release/.*)$ ]]; then
     echo "Push rejected: direct pushes to 'master/' or 'release/*' branches are not allowed."
     echo "Please use a pull request instead."
     exit 1
  fi

  if [[ "$refname" == "$FORBIDDEN_BRANCH" ]]; then
    echo "Push rejected: pushing to 'forbidden-branch' is not allowed."
    echo " Please create a branch with an approved naming convention."
    echo "Branch name starting with <user-id>/<org>/*
 are only allowed."
    exit 1
  fi
done

exit 0

Instead create a simple ruleset to avoid push from unknown branches by creating a new ruleset:

  1. Go to settings and select rulesets
  2. Select the ruleset
  3. Now add necessary details about Ruleset Name, Enforcements, Bypass list and Target branches.
  4. New branch ruleset

  5. Now scroll down to bottom and fill the details to optimize the workflow
  6. Add the branch name spacing pattern

    Finally

    and done 🥳🥳.
    This will atomically trigger whenever user tries to push new branches.

    Conclusion:

    Branch Protection Rules are not obsolete—they still provide essential safeguards for critical branches. But as repositories grow and governance requirements become more complex, relying solely on branch-by-branch configuration and custom hooks starts to introduce friction, duplication, and maintenance overhead. Rulesets represent a shift from reactive protection to proactive governance, allowing policies to be defined once and applied consistently as repositories evolve.

    The real value of rulesets is not just fewer clicks in the UI, but a clearer separation of concerns: platform-level policies enforced centrally, and developer workflows kept simple and predictable. When used correctly, rulesets eliminate the need for many custom server-side hooks, reduce configuration drift, and make repository standards easier to scale across teams and organizations. In short, branch protection rules secure branches—but rulesets secure the process. If you want to use it in your repository, read about management here

Top comments (1)

Collapse
 
jon_p_5d69d53ab57c39767d5 profile image
Jon P

Agreed. Rulesets are better, when it comes to have checks on branch namespace before they are created.