Skip to content
C Codeloom
Git

Git Pull Request Best Practices

How to open pull requests reviewers actually enjoy: small scope, clear descriptions, good commit hygiene, useful CI, and how to handle review feedback without endless back-and-forth.

·4 min read · By Codeloom
Beginner 9 min read

What you'll learn

  • How to scope a PR so it gets reviewed quickly
  • What to put in a PR description that helps reviewers
  • Commit hygiene that survives rebase and squash
  • How to respond to feedback efficiently
  • How CI and required checks should be tuned

Prerequisites

  • Working knowledge of Git branches and a host like GitHub or GitLab

What and Why

A pull request is a conversation between you, the reviewer, and the codebase’s future maintainers. Done well, PRs accelerate teams: bugs get caught early, knowledge spreads, and shipping feels routine. Done badly, they become 2,000-line monsters that sit for a week and merge with a tired “LGTM.”

The goal is simple: make it cheap for someone else to understand the change, agree it is correct, and merge it. Everything below serves that goal.

Mental Model

Think of a PR as a unit of cognitive load. Reviewers have a budget; you want your PR to fit comfortably under it. The two main levers are size and clarity.

  • Size: smaller PRs get reviewed faster and more carefully. Aim for under ~400 lines of meaningful diff. Refactors and generated code can be larger but should be called out.
  • Clarity: the diff alone is not enough. The reviewer also needs the why, the scope boundary, and a way to verify.

A useful rule: if you cannot describe the PR in one or two sentences, it is probably two PRs.

Hands-on Example

A reasonable PR description template:

## Summary
Adds CSV export to the reports page. Users can download the same data
they see in the table, respecting current filters.

## Why
Customers have been pasting screenshots into spreadsheets. Closes #482.

## Changes
- New `/api/reports/export.csv` endpoint
- Streaming response so large exports do not exhaust memory
- Button on the reports page wired to the endpoint

## Out of scope
- Excel format (separate ticket #491)
- Scheduled exports

## How to test
1. `pnpm dev`
2. Apply any filter on /reports
3. Click "Export CSV", verify rows match the table

Commit hygiene that survives squash-merge but also tells a story:

# during the work
git commit -m "wip: sketch endpoint"
git commit -m "wip: streaming"
git commit -m "fix: tests"

# before pushing for review
git rebase -i main
# squash into logical units, e.g.:
#   feat(reports): add streaming CSV export endpoint
#   feat(reports): wire export button on UI
#   test(reports): cover filter passthrough

When feedback arrives:

# address comments in new commits, not amended ones, so reviewers can see deltas
git commit -m "review: rename param to filterQuery"
git push

# right before merge, squash if the project policy requires linear history
open
|  small scope, clear description, green CI
v
review #1
|  reviewer reads diff + description, leaves comments
v
respond
|  new commits address feedback, replies thread by thread
v
review #2
|  reviewer rechecks only the deltas
v
approve
|
v
merge (squash or rebase per project rules)
|
v
delete branch, ticket auto-closed
The lifecycle of a healthy PR

Common Pitfalls

  • Mixing refactors with features: reviewers cannot tell what is behavior change vs noise. Split them.
  • Empty description: forcing reviewers to read the diff cold burns their time and yours.
  • Force-pushing during review: rewrites history and breaks “view changes since last review.” Add commits instead until you are ready to clean up.
  • Bundling formatter or lint changes: a stray Prettier run can hide the real change. Land formatting in its own PR.
  • Ignoring CI: opening a PR with red CI signals you are not done. Wait for green.
  • Long-running branches: the longer a branch lives, the worse the merge conflict. Rebase or merge main frequently.

Practical Tips

  • Open a draft PR early to get directional feedback before you have invested a week.
  • Write commit messages in the imperative (“add”, “fix”, “remove”), with a body explaining why if it is non-obvious.
  • Use checklists in the description for self-review: tests added, docs updated, migration safe.
  • Reply to every comment with either “fixed in <sha>” or a short reason if you disagree.
  • Set up required status checks and CODEOWNERS so the right people are auto-requested.
  • Encourage reviewers to use suggestions (> ```suggestion) for small fixes; accept them with one click.

Wrap-up

Good PRs are not about following a template. They are about respecting the reviewer’s time and the codebase’s future. Keep them small, describe the why, keep CI green, and respond to feedback transparently. Do that consistently and code review stops being a bottleneck and starts being the best part of shipping software.