Pull Requests
What is a Pull Request?
A Pull Request (PR) is a way to propose changes from one branch to another. When you're done working on a feature or fix, you open a PR to ask your team to review your code before it's merged into the main branch.
Pull requests are the backbone of collaborative development on GitHub. They give your team a dedicated place to:
- Review and discuss your changes
- Leave comments on specific lines of code
- Request changes or approve the work
- Run automated checks (CI/CD)
- Merge once everything looks good
The Pull Request Workflow
1. Create a branch → git checkout -b feature/login
2. Make your changes → write code, commit
3. Push the branch → git push origin feature/login
4. Open a PR on GitHub → propose merging into main
5. Team reviews it → comments, approval
6. Merge the PR → changes land in main
7. Delete the branch → cleanup
Creating a Pull Request
Step 1: Push Your Branch
After committing your work locally, push the branch to GitHub:
git push origin feature/login
Step 2: Open the PR
Go to your repository on GitHub. You'll see a banner: "feature/login had recent pushes — Compare & pull request". Click it.
Alternatively, go to the Pull requests tab → New pull request.
Step 3: Fill in the PR Details
A good PR description saves reviewers time. Include:
Title: Short and descriptive — what does this PR do?
Add user login with JWT authentication
Description: Explain the what, why, and how:
## What changed
- Added `/api/auth/login` endpoint
- JWT token stored in httpOnly cookie
- Added `requireAuth` middleware for protected routes
## Why
Users need to authenticate to access their data. Closes #42.
## How to test
1. POST to `/api/auth/login` with `{ email, password }`
2. Should receive a JWT token in the response
3. Use the token in the `Authorization` header for protected routes
Step 4: Set Reviewers and Labels
On the right sidebar:
- Reviewers — tag teammates who should review your changes
- Labels — tag the type of change (
bug,feature,documentation) - Assignees — usually yourself (who's responsible for this PR)
- Milestone — link to a sprint or release if applicable
Reviewing a Pull Request
When you're asked to review someone else's PR:
Leave Line Comments
Click the + icon next to any line to leave a comment on that specific line. Use this for specific feedback:
This function is doing too much — could we extract the validation logic?
Start a Review
Instead of submitting individual comments one by one, click "Start a review" to batch all your comments and submit them together. This prevents the author from getting 10 separate notifications.
Review States
When you submit your review, choose one of:
| State | Meaning |
|---|---|
| Comment | General feedback, no explicit approval or rejection |
| Approve | LGTM — ready to merge |
| Request changes | Changes needed before this can be merged |
Review Etiquette
- Be specific and constructive: "This could cause a null pointer if
useris undefined" instead of "this is wrong" - Distinguish blocking from non-blocking feedback: prefix suggestions with
nit:for nitpicks - Ask questions instead of making assumptions: "Why did you choose this approach over X?"
- Approve when it's good enough — perfect is the enemy of done
Responding to Review Feedback
As the PR author:
- Read each comment carefully
- Make the requested changes in new commits (don't force-push during review)
- Reply to each comment explaining what you changed or why you disagree
- Click "Resolve conversation" once a comment is addressed
- Re-request review from the reviewer
Don't squash commits during review — it makes it harder for reviewers to see what changed since their last review. Squash after approval, before merge.
Merging a Pull Request
Once approved, you have three merge strategies:
Merge Commit
main: A --- B --- C --- M (M is the merge commit)
\ /
feature: D - E
Preserves the full history of the feature branch. Use for significant features.
Squash and Merge
main: A --- B --- C --- DE (D+E squashed into one commit)
Combines all PR commits into a single commit on main. Keeps main history clean. Good for small features and bug fixes.
Rebase and Merge
main: A --- B --- C --- D' --- E' (D and E rebased onto main)
Replays commits from the feature branch on top of main. Keeps a linear history.
Squash and Merge is the most common choice for teams that want a clean, linear main history. Use Merge Commit when you want to preserve the full context of a complex feature.
Closing a PR Without Merging
If a PR is no longer needed or the approach was abandoned:
- Leave a comment explaining why
- Click "Close pull request" (no merge)
The branch is not deleted automatically — delete it separately if it's no longer needed.
Draft Pull Requests
Open a PR as a Draft when you want early feedback but the code isn't ready to merge:
- Click the dropdown arrow on "Create pull request"
- Select "Create draft pull request"
This signals to reviewers that the PR is a work in progress. When ready, click "Ready for review".
Common PR Mistakes to Avoid
- Massive PRs — keep PRs small and focused. A PR with 50 files is hard to review. Aim for under 400 lines changed.
- No description — always explain what you did and why.
- Merging without approval — even if you have permission, get at least one review on significant changes.
- Ignoring CI failures — don't merge a PR with failing tests or lint errors.
- Stale PRs — keep PRs short-lived. The longer they sit, the more merge conflicts accumulate.