The collaboration layer of Git.
Branches exist because real engineering work doesn't happen in a single linear sequence. At any given moment, a team of five might have three features in progress, a bug fix in review, and an infrastructure change waiting for a deploy window. Without branches, all of that work would collide in a single shared workspace — half-finished features breaking each other, a bug fix accidentally shipping with an incomplete feature, infrastructure changes tangling with product code.
A branch gives each stream of work its own isolated context. You can break things, experiment, refactor aggressively — and none of it affects your teammates until you explicitly choose to merge. This isolation is what makes parallel work possible without constant coordination overhead.
But isolation is only half the value. Branches also lower the cost of experimentation. Want to try a different algorithm? Branch, prototype, benchmark. If it's faster, merge. If it's not, delete the branch. Total cost: zero damage to the shared codebase, zero noise in the commit history, zero rollbacks needed. Teams that branch freely try more approaches and find better solutions. Teams that treat branching as heavyweight (or skip it entirely by committing to main) either experiment less or experiment dangerously.
A pull request is a proposal: "Here's what I changed, here's why, and I'd like someone to look at it before it merges." That sounds simple, but it represents a fundamental shift from implicit to explicit quality control.
Without PRs, code review is optional, ad-hoc, and inconsistent. Maybe someone looks at your code before it ships, maybe they don't. Maybe they look at part of it. Maybe they look at it after it's already in production. PRs make review a gate — code doesn't reach main until at least one other engineer has read it, understood the intent, and approved the approach.
This isn't about catching bugs (though it does that). It's about shared ownership. When a PR is reviewed and approved, the change isn't "Sarah's code" anymore — it's the team's code. The reviewer is saying "I understand this, I agree with the approach, and I'm comfortable maintaining it." That distributed ownership means no single engineer becomes a bottleneck or a single point of failure.
PRs also create a decision record. The description explains the why, the diff shows the what, and the review comments capture the trade-offs considered. Three months later, when someone asks "why did we build it this way?", the PR has the answer — including the alternatives that were discussed and rejected.
Code review goes wrong when it becomes a gatekeeping ritual — one senior engineer blocking merges with style nitpicks while the team waits. That's not review; that's a bottleneck dressed up as quality.
Good code review is a conversation between peers. The reviewer's job isn't to prove they know more — it's to ask "did I understand your intent?" and "did you consider this edge case?" The best review comments are questions, not directives. "What happens if this list is empty?" teaches more than "Add a null check here."
Three principles that keep review productive:
Review culture is also one of the most effective onboarding tools a team has. A new engineer reading PR reviews learns the team's patterns, preferences, and past mistakes faster than any documentation could teach them. The review archive is a living style guide.
Long-lived branches are technical debt
Every day a branch lives apart from main, the merge gets harder. Branches should live days, not weeks.