Where does GitHub look for a CODEOWNERS file, and which branch's copy governs a pull request?
answer
- Only a few directories are allowed
- One file, not merged across locations
- Versioned like any other tracked file
- The base branch decides
basics
~20 sGitHub reads CODEOWNERS from the .github directory, the repository root, or docs — the first one it finds, in that order, and only one file is used. The copy that applies to a pull request is the one on the base branch it targets.
solid answer
~50 sThe file must be named `CODEOWNERS` and live in one of exactly three places: `.github/`, the repository root, or `docs/`. GitHub searches those locations in that order and uses the **first** file it finds; a second copy elsewhere is ignored, and a `CODEOWNERS` dropped into an arbitrary subdirectory does nothing at all. Crucially, CODEOWNERS is a **per-branch** file: the rules that apply to a pull request are the ones committed on the pull request's **base** branch, not on the head branch. That is why editing CODEOWNERS inside a pull request does not change who is requested on that same pull request — the new rules only take effect once they land on the target branch. It also means a branch that has never received the file has no code owners, however well protected the default branch is.
code
text · 4 lines.github/CODEOWNERS <- searched first, and the usual choice
CODEOWNERS <- repository root, searched next
docs/CODEOWNERS <- searched last
src/CODEOWNERS <- ignored; not a valid locationgo deeper
Know the three legal locations — .github, the repository root, docs — and that the file is named CODEOWNERS with no extension. Anywhere else and GitHub ignores it entirely.
Explain that only the first file found is used and that ownership is resolved from the pull request's base branch, so rules added inside a pull request do not apply to that pull request.
Bring the operational angle: ownership drifts on long-lived release branches, the errors view is your check after an edit, and the file itself should be owned so ownership changes get reviewed.
Frame it as configuration that is versioned per branch — decide where ownership metadata lives, how it is kept consistent across release lines, and who is accountable for changes to the ownership map.
## The three valid locations GitHub looks for a file named exactly `CODEOWNERS` (uppercase, no extension) in three directories: - `.github/CODEOWNERS` - `CODEOWNERS` at the repository root - `docs/CODEOWNERS` It searches those locations in that order and uses the first file it finds. If a repository has more than one, the others are simply ignored — there is no merging of rules across locations, and no way to split ownership across several files. A `CODEOWNERS` placed in `src/` or any other directory is an ordinary text file with no meaning to GitHub. Most teams standardise on `.github/CODEOWNERS` because it keeps repository metadata together with issue templates, workflows and the pull request template rather than cluttering the root. ## CODEOWNERS is per-branch This is the part candidates miss. `CODEOWNERS` is a tracked file in the repository, so it is versioned per branch like any other file — and GitHub resolves ownership for a pull request using the copy on the pull request's **base** branch (the branch you are merging *into*), not the head branch carrying your changes. Three practical consequences: 1. **Editing CODEOWNERS in a pull request does not affect that pull request.** If your branch adds `/infra/ @my-org/sre`, the SRE team is not requested on the pull request that introduces the rule, because the base branch does not have it yet. The rule starts working on the next pull request opened after the merge. Teams are sometimes surprised to see the *old* owners requested on the very change that reassigns ownership; that is correct behaviour, and it is also a safety property — you cannot merge a change that quietly hands ownership of a directory to yourself and have it take effect on that same change. 2. **Long-lived release branches need their own copy.** If you cut `release/2.0` before CODEOWNERS existed, or from a point where it looked different, pull requests targeting that branch use the version that lives there. Ownership can drift silently between branches. 3. **A pull request from a fork still uses the upstream base branch's file.** The contributor's fork can contain whatever CODEOWNERS it likes; only the base repository's base branch matters. ## Errors and the file view When you browse `CODEOWNERS` on GitHub, invalid lines — unknown users or teams, owners without write access, malformed patterns — are surfaced in a CODEOWNERS errors view, and a pull request that edits the file is annotated with the same problems. Checking that view after an edit is the cheapest way to confirm the file will actually do something, because a broken rule fails silently at pull request time. ## Protecting the file itself Since CODEOWNERS determines who must approve changes, the file is worth owning explicitly with a rule for `/.github/CODEOWNERS`. With required code owner review enabled on the branch, that line makes any change to ownership itself go through the named team. Without it, anyone who can open a pull request against a directory can propose reassigning its owners; the base-branch rule prevents the change from being self-applying, but it does not by itself require a specific reviewer. ## Interaction with enforcement Merely committing the file does not gate merges; it makes GitHub auto-request the owners of changed files when a pull request is opened. Blocking a merge until an owner approves is a separate setting on the target branch (required review from code owners, via branch protection or a repository ruleset). Because both the file and the setting are per-branch concerns, a common misconfiguration is a well-written CODEOWNERS on `main` with the protection applied to a branch pattern that does not match the branches people actually target. ## Debugging checklist When owners are not being requested, verify in order: the file is in one of the three valid locations and spelled `CODEOWNERS`; only one copy exists (or the intended one is first in search order); the file exists **on the base branch** of the pull request; the errors view is clean; and the target branch actually requires code owner review if you expected the merge to be blocked.
- A pull request adds new CODEOWNERS rules. Are the new owners requested on that pull request?No. GitHub resolves ownership from the base branch's copy, which does not yet contain the new rules, so the old owners are requested. The new rules take effect for pull requests opened after the change merges. This also prevents a contributor from granting themselves ownership in the same change that uses it.
- Two copies of CODEOWNERS exist, at the root and in .github. Which one applies?Only one file is ever used — GitHub searches .github, then the repository root, then docs, and takes the first it finds, so the .github copy wins and the root copy is dead weight. There is no merging of rules across locations, so the ignored file is a maintenance trap worth deleting.
- Why might a long-lived release branch have different code owners than main?Because CODEOWNERS is a tracked file resolved from the base branch. A release branch cut before a rule was added, or never updated afterwards, carries the older ownership map, so pull requests targeting it request different people. Keeping ownership consistent means backporting CODEOWNERS changes like any other fix.
saying these in an interview costs you the question
- Putting CODEOWNERS in an arbitrary subdirectory
- Expecting rules added in a PR to apply to that PR
- Assuming several CODEOWNERS files are merged
- Thinking the head branch's copy is used
- Assuming the file alone blocks merging