How to write your first pull request (and survive code review)

Your code is judged on whether it works. Your pull request is judged on whether a busy senior engineer can review it without hating their day. The first one is technical. The second one is the actual skill nobody teaches you.

Why pull request quality matters more than you think

A senior engineer reviews maybe 5–10 PRs per day. They are not reading your code with infinite patience. If your PR is 1,500 lines long, touches 20 files, has no description, and the title is "fix bug" — they will procrastinate reviewing it. It will sit in their queue for three days. By the time they get to it, main has moved on and you have merge conflicts.

If your PR is 80 lines, touches 3 files, has a clear title and a 4-line description that says what changed and why — they review it in 5 minutes during coffee. You merge same day. Multiply this across the summer and you have shipped 30 things vs. 8.

Pull request quality is the single highest-leverage thing you can improve as an intern. Here's the playbook.

Rule 1: Keep PRs small

Target: under 400 lines of changed code per PR. Under 200 is even better. The relationship between PR size and time-to-merge is not linear — it's exponential. A 100-line PR gets reviewed today. A 1000-line PR sits for a week.

If your work is bigger than 400 lines, split it:

Each one merges cleanly. Each one is reviewable in under 10 minutes. Each one is reversible if it breaks something.

Rule 2: Title format — what changed, in 60 characters

The title shows up in the team's PR list, in commit history, and in the eventual merge commit. Make it scannable. Use the conventional commits format:

fix: return 400 instead of 500 when email is null
feat: add password reset flow via email
chore: upgrade React to 18.3
docs: clarify env var setup in README

Bad titles to avoid:

"Fixes"
"Bug fix"
"Update users.py"
"WIP do not merge"      // (use draft PRs instead)
"Misc improvements"     // (your reviewer will hate you)

Rule 3: The PR description template

Every good PR description answers three questions: why, what, and how to verify. Here's a template you can use verbatim:

## Why
Users were getting 500 errors when their email field was null,
which happens for accounts created before the email-required migration.

## What changed
- Added a null check in `get_user_by_email`
- Returns 400 with a clear error message instead of crashing
- Added a test for the null-email case

## How to verify
1. Run `pytest tests/test_users.py::test_null_email`
2. Or hit `GET /api/users?email=` — should return 400, not 500

## Notes for the reviewer
The 400 message wording matches the existing pattern in
`api/auth.py` — happy to change it if there's a different convention.

That's it. Five minutes to write. Saves your reviewer 20 minutes of figuring out what your PR is about. Worth it every single time.

Practice writing PRs on real bugs

InternQuest gives you 150+ tickets where you fix a real bug, write a real PR description, and get automated review feedback. Same skill, no real-world consequences.

Start practicing →

Rule 4: Self-review before requesting review

Open your own PR in GitHub before tagging anyone. Read it diff-by-diff like a stranger would. You will find at least one of these every time:

Catching these yourself instead of having your reviewer point them out is the difference between "this intern is sharp" and "this intern needs hand-holding." It takes 2 minutes.

Rule 5: How to respond to review feedback without losing your mind

Code review feels personal. It isn't. Reviewers are not attacking you — they're trying to make the code better. Three rules for staying sane:

Don't argue. Discuss.

Bad: "That's not actually wrong, the original code does the same thing."

Good: "Good point — I see what you mean. I matched the pattern in users.py:42, but happy to change it. Want me to update both, or leave both as-is?"

Reviewers are right more often than they're wrong. When they're wrong, explain your reasoning calmly and ask their preference. Don't dig in.

Resolve every comment thread

For each comment: either change the code, or reply explaining why you didn't, or both. Then click "Resolve conversation." Don't leave 40 dangling threads — your reviewer can't tell which ones you addressed.

Don't take "nits" personally

A "nit" is a small style preference ("nit: I'd prefer fooBar over foo_bar here"). It is explicitly low-priority — you can choose to address it or not. If you address it, fine. If you don't, reply with "I'd rather keep this one for consistency with the file" and resolve. Either is acceptable.

Some senior reviewers leave too many nits. That's a them-problem, not a you-problem. Don't burn out fixing every single one.

Rule 6: When to push back

You should push back when:

You should not push back when:

The PR anti-patterns that mark you as a beginner

The merge moment

You got an approval. CI is green. Time to merge.

Most teams use "Squash and merge" — this collapses all your commits into one clean entry on main. Set the squash commit message to your PR title (it usually defaults to that). Click merge. Delete the branch.

Then leave a one-line "thanks for the review!" comment on the PR. Costs nothing. Reviewers remember.

The skill in one sentence

Imagine your reviewer has 20 PRs to review today and a meeting in 30 minutes. Make their job easy. That's the whole skill.

Get reviewed like a real intern

InternQuest's automated reviewer gives you line-by-line feedback on your code — same loop as a real PR. You'll have written 30 PRs before your first day.

Start your first mission →