Build the mental model
Branch protection rules let a repository owner enforce, at the platform level, that certain guarantees always hold for an important branch, usually main, no matter who is pushing or how experienced they are. Instead of trusting everyone to remember the team's process, GitHub can simply refuse to let a change bypass it.
- Every change must arrive through a reviewed pull request rather than a direct push.
- At least one — often more — approving review is required before merging is allowed.
- Configured status checks, like a test suite or a linter, must pass first.
- Force-pushes and branch deletion can be blocked entirely on the protected branch.
The exact wording and layout of these settings changes over time as GitHub updates its interface, so this lesson describes the underlying concepts rather than exact menu paths.
Beyond a single repository, GitHub Organizations let a company manage many repositories and many people together: teams group people, and permissions like read, write, or admin are granted to a team on a repository rather than configured person by person.
A related, genuinely open question every growing engineering org faces is monorepo versus multi-repo. A single monorepo makes cross-project changes atomic and keeps shared code trivially reusable, but its history and build tooling can grow heavy. Separate repos per project give independent deploy pipelines and cleaner team ownership boundaries, at the cost of coordinating changes spanning more than one. Neither is universally better.
PROTECTED MAIN: ONLY REVIEWED, PASSING PRS GET IN
-------------------------------------------------
direct push ----X BLOCKED (branch protection rule)
|
feature branch --> pull request --> review required
| |
| checks must pass
| |
+------> merge allowed -----> mainConnect it to a real scenario
There is no terminal command to demonstrate here; branch protection is entirely repository configuration on GitHub's website, under a repository's Settings, Branches, and there is nothing locally runnable that would exercise it honestly. What follows is accurate behavioral prose describing what actually happens, not a captured transcript.
Direct push is rejected
With pull-request reviews required, a direct git push origin main from anyone's machine, including an admin's in most configurations, is rejected by GitHub's server before the objects are even accepted, with an error to the effect of the branch being protected and requiring a pull request.
Commits aren't lost
The commits are not lost, they simply never land on main; the usual next step is pushing them to a new branch and opening a pull request normally.
Force-push is blocked too
If force-push protection is enabled, git push --force origin main is rejected the same way, regardless of who is pushing, closing off the most destructive way shared history can be damaged.
Status checks gate the merge button
A pull request's merge button stays disabled by GitHub until every required check reports success, even once the required review approvals are already in place.
Try the working example
# Illustrative only -- branch protection is GitHub-side configuration,
# not reproducible as a local git command. Not executed for this lesson.
git push origin main
# rejected: GitHub blocks the push because main requires a pull request
git push --force origin main
# rejected: force-pushes are blocked on a protected branchNot something you run directly
This section describes GitHub's web-platform behavior, not something you run in a terminal directly (creating a PR/Issue, a repository's branch-protection settings, an Actions run triggering — these happen on GitHub's servers). Follow along in your own real GitHub repository.
This lesson's runnable field is false because branch protection has no local git-command equivalent to execute; nothing above was run. The behavior described matches GitHub's documented branch protection rules: a direct or forced push to a protected branch is rejected server-side, and merging stays blocked until required reviews and status checks are satisfied. Treat the error text as accurate in substance, not as a literal quoted transcript from a specific GitHub screen, since exact wording changes as GitHub updates its UI.5-minute try-it
On a real GitHub repository you control, enable branch protection on main requiring pull requests and at least one review. Try pushing directly to main and read the exact rejection message GitHub gives you. Then discuss with a partner: would your current team benefit from a monorepo or from splitting into multiple repos, and why?
One important caution
Assuming an admin can always bypass branch protection by default — most sensible configurations apply the rule to admins too, and relying on an exception that may not exist is a false sense of safety.
Choosing monorepo or multi-repo based on what's currently trendy rather than your team's actual coordination needs and deploy independence requirements.
GitHub Docs - About protected branches — Git & GitHub