Branch protection fails in two ways: too little of it, and so much of it that the team routes around it. For a small team, three rules do most of the work.
1. Require a pull request and one review#
Nobody pushes straight to main, including the senior who “just fixes a typo”. One reviewer is enough at this size — the point is a second pair of eyes, not a committee.
2. Require checks to pass#
The test suite runs on the PR and must be green before merge. This is what keeps “main always runs” true in practice rather than in principle. If the suite is slow, fix the suite — do not downgrade the rule to “tests optional”.
3. No force-pushes to main#
Shared history is append-only. Rewriting main breaks everyone’s clones and makes the audit trail meaningless. Rebasing stays on feature branches, where it belongs.
What to leave out until it hurts#
Code-owner reviews, signed-commit requirements, linear-history-only, status checks from five tools — each adds friction that makes sense at a specific size or risk level. Add them when a real incident names the need, not because the settings page offers them.
The test of a ruleset is whether the team still respects it in month six. Small and enforced beats thorough and bypassed.
Share this post
Keep reading
Merging vs Rebasing on a Small Team
Rebase to tidy your own branch, merge to combine into main. One sentence of policy saves a lot of history arguments.
Trunk-Based Development on a Small Laravel Team
Short-lived branches into main beat long feature branches: smaller merges, a main that always runs, and deploys that stay boring.
Code Review Habits That Keep Main Clean
Small changes, clear descriptions and fast feedback.