bigonotes
Engineering PracticesGit and Code Review

Writing a Good Pull Request

How to write pull requests that get reviewed fast: keep them small, describe them well, review your own diff and handle feedback.

5 min readLast updated

A pull request (PR) asks your team to review a change and merge it into the main branch. GitLab calls it a merge request, and some companies call it a change list (CL). The quality of your PR decides how fast it gets reviewed and how many bugs the reviewer can catch. A good PR respects the reviewer's time, and that pays you back in faster, better reviews.

Keep it small and focused#

The single biggest thing you control is size. One PR should do one thing. Small PRs are faster to review, easier to reason about and safer to roll back.

  • One purpose per PR. A bug fix, a refactor and a new feature are three PRs.
  • Separate refactors from behavior changes. A reviewer can approve a pure rename quickly. Mixed with logic changes, it hides the real diff.
  • Aim for a size a reviewer can read in one sitting. Google's guidance says about 100 changed lines is usually reasonable, and 1,000 is usually too large.
  • Include the tests with the code. Tests belong in the same PR as the change they cover.

Line counts can mislead, though. Generated files, lockfiles and moved files inflate the count. Point them out in the description so the reviewer can skip them.

Write a clear title and description#

A small PR still needs context. The title and description are the first things a reviewer reads, and they should explain the change before the reviewer opens a single file.

Write the title like a commit subject: short, imperative and specific. "Fix timeout in login request" is better than "Login fixes". Then fill in the description with these parts.

Part What to write
What One or two sentences on what the change does
Why The problem or ticket it solves, with a link
How tested Unit tests, manual steps, or the environment you checked
Risks What could break, rollout plan, feature flag, migration
Screenshots Before and after, for any UI change

Leave out parts that don't apply, but always keep What and Why. Many repositories have a PR template that asks for these parts. Fill it in properly instead of deleting it.

Review your own PR first#

Before anyone else reads your diff, read it yourself in the review tool. You'll catch a surprising number of problems this way.

Check for these before you request a review:

  • Debug prints, commented-out code and stray TODOs
  • Files you didn't mean to change
  • Missing tests for new behavior and edge cases
  • Names that made sense while coding but not to a new reader
  • Confusing logic that needs a short code comment

Add your own comments on lines that need context, such as "This mirrors the retry logic in billing/client.py". Open the PR as a draft if you want early feedback but the work isn't ready to merge.

Stack large changes#

The "keep it small" rule raises an obvious question: what about features that are too big for one small PR? Stacking splits the work into a chain of PRs, where each one builds on the one before. Here's the flow for two parts:

  1. Create branch part-1 from main and open PR 1 against main.
  2. Create branch part-2 from part-1 and open PR 2 against part-1.
  3. Get PR 1 reviewed and merged first.
  4. Rebase part-2 onto main and change PR 2's target to main.

Each PR stays small, and reviewers see one logical step at a time. The cost is extra rebasing when an early PR changes. If PR 1 was squash-merged, use git rebase --onto main part-1 part-2 so that Git skips the old commits. A common order for a stack is data model first, then backend logic, then UI.

Respond to feedback#

Once the review starts, comments come in. They're about the code, not about you, so treat each one as information.

  • Reply to every comment. Say "Done", explain why you disagree, or ask a question.
  • Push fixes as new commits during review. Reviewers can then see only what changed since their last pass. Squash at merge time if your team does that.
  • Explain in the code, not only in the thread. If a reviewer was confused, the next reader will be too. A clearer name or a comment fixes it for everyone.
  • Disagree with reasons. Give evidence, such as a benchmark, a doc or a test. If the thread goes back and forth more than twice, talk on a call.
  • Let the reviewer resolve their own threads, unless your team has a different rule.

When a review asks for a big redesign, stop and agree on the approach before you write more code. A short design discussion is cheaper than a second large PR.

Keep CI green#

Reviewers aren't the only ones checking your PR. Continuous integration (CI) runs builds, tests and linters on every push, and most teams don't review a PR until CI passes.

  • Run the tests and linter locally before you push.
  • Fix a red build quickly, or move the PR back to draft.
  • Don't retry a flaky test (one that passes and fails at random) until it passes and then ignore it. Report it or fix it.
  • Rebase on main before merge if your branch is out of date, and let CI run again.

A green build tells the reviewer that the basics work. They can then spend their attention on design and correctness.

Key takeaways#

  • One purpose per PR, small enough to read in one sitting.
  • The description answers what, why, how tested and risks.
  • Review your own diff before anyone else does.
  • Stack PRs to split large features into reviewable steps.
  • Reply to every comment, and fix confusion in the code itself.
  • Keep CI green so reviewers can focus on the logic.
Revision notes · 2 min

Core idea#

A pull request (PR) asks the team to review a change and merge it into main. A small, well-described PR gets reviewed faster and lets the reviewer catch more bugs.

Key points#

  • One purpose per PR. A bug fix, a refactor and a feature are three PRs.
  • Separate refactors from behavior changes, so the real diff stays visible.
  • Google's guidance: about 100 changed lines is usually reasonable; 1,000 is usually too large.
  • Put tests in the same PR as the code they cover.
  • Write the title like a commit subject: short, imperative, specific.
  • Review your own diff first: debug prints, stray files, missing tests, unclear names.
  • Open a draft PR for early feedback on unfinished work.

Description#

Part What to write
What One or two sentences on the change
Why The problem or ticket, with a link
How tested Unit tests, manual steps, environment
Risks What could break, rollout, flag, migration
Screenshots Before and after, for UI changes

Always keep What and Why. Point out generated files and lockfiles, so reviewers skip them.

Stacking large changes#

  • Branch part-2 from part-1, and open PR 2 against part-1.
  • Merge PR 1, then rebase part-2 onto main and retarget PR 2.
  • If PR 1 was squash-merged, run git rebase --onto main part-1 part-2.
  • A common order is data model, then backend logic, then UI.

Handling feedback and CI#

  • Reply to every comment: "Done", a reasoned disagreement, or a question.
  • Push fixes as new commits during review. Squash at merge if the team does.
  • Fix confusion in the code with a clearer name or comment, not only in the thread.
  • Move to a call if a thread goes back and forth more than twice.
  • Keep CI green. Run tests and linter locally before you push.

Pitfalls#

  • Mixing a rename with logic changes hides the real diff.
  • Writing more code after a reviewer asks for a redesign. Agree on the approach first.
  • Retrying a flaky test until it passes. Report or fix it.
  • Deleting the PR template instead of filling it in.

Say it in an interview#

  • "One purpose per PR, small enough to read in one sitting."
  • "The description answers what, why, how tested and risks."
  • "For big features, I stack PRs so each one is one logical step."

Found a mistake? Email ask@bigonotes.com

Further reading#