The protected-branch mindset and why it's non-negotiable.
"Main is always green" means one thing: at any point in time, the main branch is deployable to production. Not "mostly works," not "works if you know which commits to skip" — deployable. Right now. Without manual intervention.
This is a higher bar than most teams realize. It means every commit on main has passed automated tests, has been reviewed by a human, and doesn't depend on incomplete work from another branch. It means you can deploy on Friday at 4 PM without anxiety, because main isn't a work-in-progress — it's the finished product at every commit.
The mechanism that enforces this is continuous integration (CI). Every PR runs the test suite, the linter, and the type checker before it can merge. If any check fails, the PR is blocked. The engineer fixes the issue on their branch — not on main, not after merging, not "later." CI is the gatekeeper that ensures main never degrades.
Teams without this discipline regularly find themselves in a state where main is broken and nobody knows which of the last five merges caused it. At that point, everyone on the team is blocked — they can't pull fresh code, can't start new branches from a working state, and can't deploy. The cost of a red main isn't one engineer's problem. It's the whole team's problem, compounding every minute it stays broken.
Branch protection rules are the automated enforcement of "main is always green." Every major Git hosting platform — GitHub, GitLab, Bitbucket — supports them, and they should be configured on day one of any serious project.
The three rules that matter most:
Some teams resist protection rules because they feel like friction. They are friction — intentional friction that prevents the most expensive class of mistakes. Configuring these rules takes five minutes. Recovering from a force-push that overwrites a teammate's work takes hours, plus the trust damage. The math isn't close.
When a deploy breaks production, engineers face a choice: fix forward or revert. The instinct is almost always to fix forward — find the bug, write a patch, push it. But that instinct is wrong under pressure.
A revert is a single command that undoes a known commit cleanly:
git revert abc123f
# Creates a new commit that undoes abc123f
# Main is green again in minutes
The panic-fix alternative looks like this: an engineer hunched over their keyboard at 11 PM, writing new code under pressure, skipping tests because "it's just a one-line fix," pushing directly to main because "we don't have time for a PR." That one-line fix introduces a second bug 40% of the time, because code written under adrenaline is code written without full context.
The rule is simple: revert first, fix later. Get main back to green immediately — that unblocks the whole team and stops the bleeding. Then, with the pressure off, write a proper fix on a branch with tests, review, and CI. The fix ships an hour or a day later, but it ships correctly.
Reverts feel like admitting failure. They're not. They're the fastest path back to a working state, and they leave the original commit in the history as documentation of what went wrong. A team that reverts quickly is a team that ships confidently, because the cost of a bad deploy is minutes of downtime rather than hours of firefighting.
If main is broken, the team is blocked
Every minute main is red, every engineer pulling new work is blocked. That's why protection rules exist.