In a shared monorepo hosted on GitHub or GitLab, what does a CODEOWNERS file do, and how does it change what happens when someone opens a pull request?
answer
- glob-to-owner mapping file
- auto-requested reviewer
- branch protection = hard gate
- last-match-wins precedence
- review-only, not code enforcement
basics
~10 sA CODEOWNERS file maps folders/files to people or teams. When a PR touches those files, the platform automatically asks the listed owners to review, and can require their approval before merge.
solid answer
~40 sCODEOWNERS is a plain-text file (e.g. `.github/CODEOWNERS`) with glob-pattern-to-owner mappings, like `/services/payments/ @team-payments`. When a PR changes files matching a pattern, the platform auto-requests review from the mapped owner(s). Combined with a branch protection rule 'require review from code owners,' it becomes a hard merge gate: the PR can't merge without an approving review from someone in that entry. It's evaluated per-PR against the diff's touched paths, last-matching-pattern-wins on conflicts, and it only governs review requirement, not build/runtime access — it doesn't stop code from importing an owned module, and it doesn't stop someone with write access from opening the PR in the first place; it just decides who must approve it.
go deeper
Should know CODEOWNERS exists and maps paths to reviewers; doesn't need precedence rules or the branch-protection interplay.
Should know pattern precedence, that branch protection is needed to make it a hard gate, and how to write scoped patterns for subteams.
Should design ownership maps for large repos (nested overrides, team vs. individual entries) and know its limits — a review gate only, not access or import control.
Should reason about ownership-model choices across the org — single vs. per-domain CODEOWNERS files, tooling to keep them synced with team topology, and when to layer build-tool enforcement on top.
## What the file is A CODEOWNERS file is a plain-text convention (supported natively by GitHub, GitLab, and Bitbucket, and implemented independently by tools like Google's internal OWNERS files and Gerrit) that lives at a fixed path in a repository — typically `.github/CODEOWNERS`, `.gitlab/CODEOWNERS`, or the repo root — and maps **file-path glob patterns** to one or more **owners**, where an owner can be an individual username or a team/group handle. A typical line looks like `/services/payments/ @org/payments-team`, meaning any file under that directory is 'owned' by the payments team. ## How a pull request is matched The mechanism itself is simple. Whenever someone opens a pull request, the hosting platform: 1. diffs the PR against the target branch; 2. walks every changed file path; 3. for each one finds the *last* matching pattern in the CODEOWNERS file — patterns are evaluated top-to-bottom, and, like a `.gitignore` file, a later, more specific pattern overrides an earlier, more general one. The **union of owners** for all matched patterns across the whole diff becomes the set of reviewers the platform automatically requests. ## From convenience to policy By itself, that's just a convenience — it saves someone from manually figuring out who to ping. The mechanism becomes a real *policy* only when paired with a **branch protection rule**, commonly labeled 'Require review from Code Owners,' on the target branch. - **With that rule enabled**, the merge button is disabled until at least one person from every matched owner group has submitted an approving review — this is what makes CODEOWNERS a hard gate rather than a suggestion. - **Without that rule**, CODEOWNERS is purely advisory: reviewers get auto-requested, but anyone with merge permission can still merge without their approval. ## Why it exists The reason this exists is that as a codebase and organization grow, 'everyone reviews everything' doesn't scale — most engineers in a large monorepo have neither the context nor the standing to meaningfully review a change to a module they've never touched, and asking them to try produces rubber-stamp approvals or bottlenecks on whoever happens to be online. CODEOWNERS routes review responsibility to the people who actually understand a given area, automatically, without relying on the PR author to remember who that is — which matters especially for new hires and cross-team contributors who don't yet know the informal ownership map. ## The trade-off The trade-off is that CODEOWNERS only governs who must approve a merge, nothing else. - It **does not restrict who can open a PR** against those files — anyone with write access can propose the change. - It **doesn't prevent another module from importing** or depending on owned code — that's a build-time concern handled by separate tooling (visibility rules, module-boundary linting). - It **doesn't validate that the reviewer actually understood the change**; a rubber-stamp approval satisfies the gate exactly as well as a careful review. So CODEOWNERS solves the 'who reviews this' routing problem but nothing about review quality or architectural correctness. ## Failure modes Failure modes recur in a few recognizable ways. - **Individual-named owners** (`@jane` rather than `@team-x`) create single points of failure: if Jane is on leave or has left and the entry wasn't updated, every PR touching that path stalls with no automatic fallback — most platforms have no 'escalate after N days' behavior, so this needs team-based entries or a monitoring bot. - **Precedence bugs** are common: someone adds a more specific pattern below an old one expecting it to be additive, not realizing it fully overrides the earlier match, silently changing who's asked to review. - **At scale**, CODEOWNERS files often balloon to thousands of lines nobody maintains carefully, drifting out of sync with actual team boundaries after reorgs. - **Coarse ownership** over widely-shared code turns a small owning team into an organization-wide bottleneck, since every consumer's PR routes through the same reviewers regardless of triviality. ## Where the convention came from A well-known real-world instance predates GitHub's native support: Chromium and many Google-internal repositories use `OWNERS` files with essentially the same semantics — per-directory ownership, inherited down the tree unless overridden, enforced by Gerrit's review tooling before a change can land — which is part of why GitHub's CODEOWNERS feature later adopted such similar syntax and behavior.
- What happens if two CODEOWNERS patterns match the same file?The last matching pattern in the file wins, the same rule .gitignore uses. Most repos put general defaults near the top and add more specific overrides below them, so it's easy to accidentally change who's asked to review by adding a new rule in the wrong place.
- Does CODEOWNERS stop someone from importing or depending on code they don't own?No — it only gates PR review on file paths, not compile-time or runtime dependencies. Stopping unwanted imports is a separate concern handled by build-tool visibility rules or module-boundary linting layered on top.
- What happens when a CODEOWNERS entry names an individual who becomes unavailable?The PR stalls waiting for a review that can't come from anyone else, since most platforms have no automatic escalation or fallback. This is why mature setups use team handles instead of individuals, plus a bot that flags requests stuck too long.
- How do teams keep CODEOWNERS accurate as they reorganize?By treating it as living config with its own owner, adding a CI check that flags entries referencing teams or users that no longer exist, and making CODEOWNERS updates a required step of the reorg process rather than an afterthought.
Like a building directory board that says 'West wing keys held by Facilities' — anyone can walk the halls, but opening a specific door still requires sign-off from the listed keyholder.
saying these in an interview costs you the question
- Thinks CODEOWNERS by itself blocks merges without branch protection enabled
- Believes it enforces which packages code can import
- Doesn't know last-match precedence, assumes first match wins
- Assumes one CODEOWNERS entry covers a whole repo instead of directory-scoped patterns
- Unaware it's advisory unless paired with a 'require review from code owners' branch protection setting