Skip to main content

Overview

A pull request (PR) is the mechanism for proposing changes to a repository and collaborating on them through activities such as review. Changes are proposed through branches: a PR is opened from the head branch, which contains what to apply, into the base branch, which is where the changes are applied, so that only approved changes are merged.

Commit messages

A commit message is a summary of the changes contained in a commit. Standardizing how messages are written as a team convention makes it possible to trace, in a consistent format, which commit in the history changed what. The Conventional Commits format is widely used for this convention: <type>: <summary>, with a prefix that indicates the kind of change. Semantic Versioning is sometimes used together with Conventional Commits. A version takes the form MAJOR.MINOR.PATCH, where the version level to bump is decided by the compatibility of the change. It is sometimes adopted in development where compatibility must be managed, such as libraries and APIs. Combining the two makes the change content easier to understand from the commit message and lets the release version be determined mechanically. When combining the two, prefix the type with the version level, as in <level>-<type>: <summary>. This makes explicit the version level that the type alone does not determine: a feature addition with a breaking change becomes major-feat, and a small feature addition that does not affect compatibility becomes patch-feat. A commit message can consist of the one-line <type>: <summary> alone. To explain the background or reason for a change, add a body — and footers as needed — after a blank line.

Titles

A PR title is a one-line summary of the change. Titles appear in PR lists, notifications, and the history after merging, so standardize a style that lets readers identify the change without opening the description. Base the title on the commit messages, using the same Conventional Commits and Semantic Versioning formats. For a PR with a single commit, reuse the commit message as the title; for a PR with multiple commits, choose the type and summary that represent the change as a whole.

Template

A PR template is a Markdown skeleton that is automatically inserted into the description field when a PR is created. With a template in place, the structure of the description — overview, changes, verification — stays consistent across PRs, and the information reviewers need is codified as a rule in advance.
1

Create the template file

Add .github/PULL_REQUEST_TEMPLATE.md to the repository.
2

Write the skeleton

Lay out the information reviewers need, separated by headings and comments.
3

Merge it into the default branch

The template takes effect only once it exists on the default branch. PRs created after the merge get the skeleton inserted into their description automatically.
Review the template regularly. Remove sections nobody fills in. If there are items that come up often as questions in review, add them as sections.

Draft

A draft is a PR state that signals the work is not yet ready for review. While a PR is a draft it cannot be merged, so unfinished changes are never pulled in by accident. Opening a PR as a draft before the work is finished lets you gather feedback on the direction of the implementation and design early, over the diff of the actual code. Unlike aligning through documents or conversation, the discussion is grounded in working code, so you and the reviewers reach a shared understanding at an early stage. Once the feedback you need is in and the understanding is aligned, you can either continue working on the same PR, or close the draft and open a new PR from scratch. The cost of changing direction grows as the work progresses, so a draft is an effective way to turn back early and keep the sunk cost to a minimum. Select “Create draft pull request” when opening the PR, and switch it out of the draft state with “Ready for review” once it is ready.

Granularity

Pull request granularity is whether a single PR concentrates on one thing — the uniformity of its change content. It is measured by whether the changes are uniform, not by the number of lines or files in the diff.

The difference between size and granularity

Size (lines and files changed) and granularity (uniformity of the change content) are different measures, and granularity is the one that drives the split decision. The test is whether the PR’s change content is uniform — the PR concentrates on one thing — not how large the diff is.

Why granularity matters

A focused diff narrows the scope that has to be reviewed. For the same total amount of work, reviewing one change ten times is lighter for both the author and the reviewer than reviewing ten changes in one PR.

Faster review

A diff with uniform change content fits in a reviewer’s head, so review stops being deferred and finishes in minutes.

Clean reverts

Reverting a PR with a single, uniform change rolls back exactly that change and nothing else.

Fewer conflicts

Short-lived branches are less likely to run into conflicts.

Faster root-cause

A PR with uniform change content also has a narrow impact area, so isolating the cause during an incident is fast.
A large, mixed PR produces a negative cycle: it raises the reviewer’s cognitive load, review is deferred, the branch lives longer, conflicts accumulate, and the next review is harder still. Granularity also matters for context management when AI agents do the work. Having an agent handle multiple requirements or unrelated changes in the same context spreads its attention and lowers precision. Splitting the work into PR units with uniform change content lets the agent focus its limited context on one thing, raising the accuracy of both implementation and review.

Tips for getting granularity right

Break work down first

Decompose the work into independently workable tasks before writing code, so each task maps to one PR. See Task Breakdown.

When in doubt, split smaller

When unsure about the right granularity, choose the smaller one. Discussing granularity within the review exchange aligns expectations with the reviewer. Splitting a PR that has already grown large is harder than starting small and coarsening the granularity later. When in doubt, ship small and flesh the work out incrementally.

Review first

Finer granularity creates more moments where the next piece of work cannot start until a merge lands. If review stalls there, it becomes the bottleneck and slows down overall development speed. So when a review request arrives, handle it before your own work. The context switch of interrupting your own work may be a concern, but reviewing a well-granulated PR takes minutes — sometimes under a minute — so the cost of the interruption is small. Keeping granularity right is what lets the review-first habit take root in the team.

Keep CI fast

Finer granularity means more PRs, and CI runs grow in proportion. If CI stays slow, the accumulated waiting before each merge erodes development efficiency instead. Aim for runs under 10 minutes, and treat anything over 5 minutes as slow enough to improve. For concrete techniques, see Keep CI fast in CI/CD.

Separate deploy from release

Treating the deploy of code and the release of a feature as separate events lets unfinished work merge without waiting for the whole feature to be done, so PRs can keep shipping small. See Release for details.