skip to content

In GitHub, what does requiring branches to be up to date add to required status checks?

level: middleimportance: must knowfreq 64%

answer

  1. green against which base, exactly
  2. the base branch keeps moving
  3. semantic conflict between two green PRs
  4. branch must contain the base tip
  5. the strict flag serialises merges

basics

~20 s

It forces the pull request branch to contain the base branch's newest commit before merging, so the required checks proved green on that exact combination. Without it, checks only prove the branch was green against an older base.

solid answer

~50 s

Required status checks name specific checks that must report success on the pull request's head commit before GitHub enables the merge button. On their own they prove only that *your branch* passed — possibly against a base commit that is now several merges stale. **"Require branches to be up to date before merging"** (the `strict` flag on GitHub's protection API) adds the condition that the PR branch must already contain the tip of the base branch; if someone else merges first, your PR is marked out of date and you must update the branch, which re-runs CI on the new combination. That closes the semantic-conflict gap where two individually-green PRs break `main` together, but it serialises merges: on a busy repository every merge invalidates every other open PR, and the cost of that is what a merge queue exists to absorb.

code

json · 14 lines
json
{
  "required_status_checks": {
    "strict": true,
    "checks": [
      { "context": "build", "app_id": null },
      { "context": "unit-tests", "app_id": null }
    ]
  },
  "required_pull_request_reviews": {
    "required_approving_review_count": 1,
    "dismiss_stale_reviews": true
  },
  "enforce_admins": { "enabled": true }
}

go deeper

for a junior

Recall that GitHub blocks the merge button until the named checks report success on the pull request's head commit, and that Update branch appears when the base has moved on.

for a middle

Explain the difference between green-against-an-old-base and green-against-the-base-you-will-land-on, and why two independently green pull requests can still break the default branch.

for a senior

Be ready to diagnose a permanently blocked pull request — renamed check, filtered workflow, fork run, wrong reporting App — and to judge when the serialisation cost of the strict flag outweighs its protection.

for a principal

Own the throughput consequence across an organization: at what merge rate strict checking stops scaling, what you adopt instead, and how much CI spend the chosen guarantee is worth.

## What a required status check is GitHub aggregates two kinds of external signal on a commit: legacy **commit statuses** (posted to the statuses API with a `context` string) and **check runs** (posted by a GitHub App, such as GitHub Actions, with a name). Branch protection lets you mark specific ones as **required**. When a pull request targets the protected branch, GitHub looks at the head commit of the PR, finds the reported results, and blocks the merge button until every required one is successful. The name matters literally: the required entry must match the reported check name character for character, and for check runs GitHub also records which App is expected to report it. Crucially, a required check that has **never reported** does not count as passing — it shows as expected/pending and blocks the merge indefinitely. This is the single most common "my PR can never merge" support ticket, and its usual causes are worth naming: the check name was renamed in the workflow but not in the branch rule; the workflow did not trigger at all (a path filter or branch filter excluded the change), in which case GitHub documents that the required check stays pending and the PR stays blocked; or the run belongs to a fork pull request whose workflows the repository does not run automatically. ## What the up-to-date requirement changes Without the strict flag, the guarantee is: *this branch, merged into whatever base it was tested against, was green*. Bases move. Suppose PR A removes a function that PR B has just started calling. Each PR's CI is green in isolation, because neither branch contains the other's change. Merge A, then merge B, and `main` is broken — nothing in either test run ever saw both changes. This is a **semantic conflict**: Git merges it cleanly because the text does not overlap, but the meaning collides. "Require branches to be up to date before merging" makes GitHub additionally check that the PR branch already contains the base branch's current tip. The moment someone else merges, every other open PR becomes out of date, the merge button is replaced by an **Update branch** action, and merging is blocked until the author brings the base in (a merge from base or a rebase, at the repository's preference) — which produces a new head commit and therefore a fresh CI run on the true combination. That run is what the guarantee upgrades to: *this branch plus the exact base it will land on was green*. ## The cost The protection is real, and so is the throughput problem. With `N` open pull requests and a strict base, each merge invalidates the other `N-1`; every author must update and wait for a full CI cycle, and only one of them can win the next slot. Merge throughput degrades toward one PR per CI duration, and developers start racing the button. Teams typically respond in one of three ways: accept the serialisation because merge volume is low; drop the strict flag and accept occasional breakage on `main` with a fast revert culture; or keep the guarantee while removing the human toil by putting a **merge queue** in front of the branch, which does the update-and-retest step automatically in landing order. ## Reading and setting it The classic representation is on the branch protection API: `required_status_checks` with `strict` (the up-to-date flag) and a list of `checks`, each an object with a `context` and an optional `app_id` pinning which App may satisfy it. Pinning `app_id` matters for security: without it, any integration that can write statuses could post a green `context` with that name. In rulesets the same rule appears as `required_status_checks` with parameters including a strict-policy flag and the list of required checks, which lets an organization apply the same requirement across many repositories at once. ## Interactions worth knowing - **Approvals are a separate rule.** "Require approvals" and "dismiss stale approvals when new commits are pushed" are independent of checks; updating a branch to satisfy the strict flag pushes a new commit, which can dismiss existing approvals if that option is on — a genuine annoyance in busy repositories. - **Conversation resolution** is another separate gate: unresolved review threads can block merging even when every check is green. - **Bypass** applies here too. Someone in a ruleset's bypass list, or an admin where bypassing is allowed, can merge past a red or missing required check, and that bypass is recorded. ## Interview framing Say what required checks prove, then state precisely what the strict flag adds (the branch must contain the base tip, so CI ran on the real combination), then name the tradeoff (serialisation on busy repositories) and the platform answer to it. Adding the "check that never reports blocks forever" failure mode shows you have operated the thing rather than only configured it.

  • A pull request can never merge because a required check is stuck as expected. What do you check?
    Whether anything ever reported that name. Common causes: the check was renamed in CI but not in the branch rule; the workflow was excluded by a path or branch filter, which leaves the required check pending and blocks the merge; the run came from a fork whose workflows are not run automatically; or the result was posted by a different App than the required check pins.
  • What is the cost of the strict flag on a repository with many concurrent pull requests?
    Every merge makes all other open pull requests out of date, so each author must update and wait for a full CI cycle before they can merge. Throughput tends toward one merge per CI duration, and developers race for the slot. A merge queue keeps the same guarantee while doing the update-and-retest automatically in landing order.
  • Why does pinning a required check to a reporting App matter?
    Required checks are matched by name. Without pinning, any integration with permission to write statuses on the repository could post a successful result using that name and satisfy the gate. Recording which App must report it means only the intended CI system can turn the check green.

saying these in an interview costs you the question

  • Says a check that never reports is treated as passing
  • Thinks required checks guarantee the merged result is green
  • Confuses required approvals with required status checks
  • Believes the strict flag rebases the branch automatically
  • Claims renaming a CI job cannot break the merge gate

context