Try free
7 min read Guide 327 of 877

Configuring Branch Protection Rules

Branch protection rules are your automated gatekeepers. They ensure code reviews happen, tests pass, and critical branches stay stable. Properly configured protection prevents costly mistakes and enforces team standards without manual policing.

Protection Options

ProtectionPurposeRecommended
Require PRNo direct push✓ Always
Require reviewCode quality✓ Always
Require CITests pass✓ Always
Up to dateNo merge conflicts✓ Usually
Block force pushPreserve history✓ Always

GitHub Configuration

Setting Up Protection

GITHUB BRANCH PROTECTION
════════════════════════

ACCESS:
─────────────────────────────────────
Settings → Branches → Add rule
├── Branch name pattern: main
└── Configure protections

REQUIRED PROTECTIONS:
─────────────────────────────────────
☑ Require a pull request before merging
├── Required approvals: 1 (small team) or 2 (larger)
├── Dismiss stale pull request approvals
│   └── Changes after approval need re-review
├── Require review from Code Owners
│   └── Use CODEOWNERS file
└── Require approval of most recent push
    └── Prevents sneaky commits after approval

☑ Require status checks to pass
├── Require branches to be up to date
├── Add checks:
│   ├── ci/build
│   ├── ci/test
│   ├── ci/lint
│   └── security/scan
└── All must pass before merge

☑ Require conversation resolution
└── All PR comments must be resolved

☑ Require signed commits (optional)
└── For high-security repos

PUSH RESTRICTIONS:
─────────────────────────────────────
☑ Restrict who can push to matching branches
├── Select allowed teams/users
├── Only for emergencies
└── Usually: nobody (all via PR)

☑ Do not allow bypassing the above settings
└── Even admins must follow rules

☑ Block force pushes
└── Protect history

☑ Block deletions
└── Can't delete protected branches

GitHub Rulesets

GITHUB RULESETS (NEWER)
═══════════════════════

ADVANTAGES OVER BRANCH RULES:
─────────────────────────────────────
├── Apply at organization level
├── Target multiple branches/repos
├── More granular bypass permissions
├── Tag rules included
├── Better audit trail
└── Recommended for enterprise

CREATING A RULESET:
─────────────────────────────────────
Repository → Settings → Rules → Rulesets

New ruleset:
├── Name: "Production Protection"
├── Enforcement: Active
├── Target branches: main, release/*
└── Configure rules

RULESET OPTIONS:
─────────────────────────────────────
Branch rules:
├── Restrict creations
├── Restrict updates
├── Restrict deletions
├── Require linear history
├── Require deployments to succeed
├── Require signed commits
├── Require a pull request
├── Require status checks
└── Block force pushes

Bypass list:
├── Repository admins
├── Specific teams (e.g., Release Team)
├── Deploy keys
└── Emergency access defined

GitLab Configuration

Protected Branches

GITLAB PROTECTED BRANCHES
═════════════════════════

ACCESS:
─────────────────────────────────────
Settings → Repository → Protected branches

CONFIGURATION:
─────────────────────────────────────
Branch: main

Allowed to merge:
├── Maintainers (common)
├── Developers + Maintainers
├── No one (via MR only)
└── Role-based control

Allowed to push:
├── No one (recommended)
├── Force CI/MR workflow
└── All changes via MR

Allowed to force push:
├── No (always)
└── Protects history

Code owner approval:
├── Required from CODEOWNERS
└── Domain expertise enforced

MERGE REQUEST SETTINGS:
─────────────────────────────────────
Settings → Merge Requests

☑ Pipelines must succeed
☑ All threads must be resolved
☑ Skipped pipelines considered successful: No
☑ Merge method: Merge commit / Squash / Rebase
└── Team preference

Status Checks

Requiring CI to Pass

STATUS CHECK CONFIGURATION
══════════════════════════

WHICH CHECKS TO REQUIRE:
─────────────────────────────────────
Essential:
├── Build: Must compile/build
├── Test: Unit tests pass
├── Lint: Code standards met
└── Non-negotiable gates

Recommended:
├── Security scan
├── Type checking
├── Integration tests
├── Coverage threshold
└── Higher quality bar

Optional:
├── Performance tests
├── Preview deployment
├── Documentation check
└── Nice-to-have

SETTING UP CHECKS:
─────────────────────────────────────
1. Create workflow that reports status:
   name: CI
   on: pull_request
   jobs:
     build:
       runs-on: ubuntu-latest
       steps:
         - uses: actions/checkout@v4
         - run: npm ci
         - run: npm run build
         - run: npm test

2. Add to required checks:
   Settings → Branches → Edit rule
   → Add "build" to required checks

HANDLING FLAKY TESTS:
─────────────────────────────────────
Options:
├── Fix the flaky test (best)
├── Retry logic in CI
├── Remove from required (temporary)
└── Don't let flaky block team

Emergency Bypass

Handling Urgent Fixes

EMERGENCY PROCEDURES
════════════════════

BYPASS OPTIONS:
─────────────────────────────────────
Option 1: Bypass list
├── Specific people can bypass
├── Senior engineers / leads
├── Emergency-only usage
├── Audited in git history
└── Define in ruleset

Option 2: Hotfix branch rules
├── hotfix/* has lighter protection
├── Maybe 1 reviewer vs 2
├── Same CI requirements
├── Faster path for urgent
└── Separate protection rule

Option 3: Temporary disable
├── Admin disables rule
├── Push fix
├── Re-enable immediately
├── Document in incident log
├── Last resort
└── Has audit trail

EMERGENCY PROCESS:
─────────────────────────────────────
1. Create hotfix/* branch
2. Make minimal fix
3. Fast review (1 person)
4. CI must pass (abbreviated)
5. Merge to main
6. Cherry-pick to release if needed
7. Full post-mortem review
8. Log in incident record

BALANCE:
─────────────────────────────────────
├── Protection is important
├── Emergencies happen
├── Define process ahead of time
├── Don't make bypasses common
├── Review after every bypass
└── Continuous improvement

Code Owners

Domain-Based Review

CODEOWNERS FILE
═══════════════

PURPOSE:
─────────────────────────────────────
├── Automatic review assignment
├── Ensure right experts review
├── Ownership of code areas
├── Required approval for changes
└── Domain expertise enforcement

FILE LOCATION:
─────────────────────────────────────
.github/CODEOWNERS
# or
docs/CODEOWNERS
# or
CODEOWNERS (root)

SYNTAX:
─────────────────────────────────────
# Default owners for everything
* @team-lead @senior-dev

# Frontend ownership
/src/components/ @frontend-team
*.tsx @frontend-team
*.css @frontend-team

# Backend ownership
/src/api/ @backend-team
/src/services/ @backend-team

# Infrastructure
/terraform/ @platform-team
/docker/ @platform-team
*.yml @devops-team

# Security sensitive
/src/auth/ @security-team @team-lead
/src/payments/ @security-team @backend-team

RESULT:
─────────────────────────────────────
├── PR touching /src/auth/ → security-team auto-added
├── Must approve for merge
├── Domain experts involved
├── No changes slip through
└── Automatic assignment

GitScrum Integration

Protection Visibility

GITSCRUM WITH BRANCH PROTECTION
═══════════════════════════════

PR STATUS VISIBILITY:
─────────────────────────────────────
On task:
├── PR status shown
├── Checks passing/failing
├── Review status
├── Merge readiness
└── At-a-glance health

WORKFLOW AWARENESS:
─────────────────────────────────────
├── Task moves "In Review" → PR opened
├── Task sees PR checks status
├── Blocked if checks fail
├── Unblocked when ready to merge
└── Task status reflects reality

Best Practices

For Branch Protection

  1. Protect main always — Non-negotiable
  2. Require reviews — Code quality gate
  3. Require CI — Automated verification
  4. Use Code Owners — Right experts review
  5. Plan emergency path — But use rarely

Anti-Patterns

BRANCH PROTECTION MISTAKES:
✗ No protection on main
✗ Admins bypass routinely
✗ Optional CI checks
✗ No required reviews
✗ Too many bypasses
✗ Force push allowed
✗ No CODEOWNERS for critical code
✗ Emergency process undefined