Skip to main content

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:

StateMeaning
CommentGeneral feedback, no explicit approval or rejection
ApproveLGTM — ready to merge
Request changesChanges needed before this can be merged

Review Etiquette

  • Be specific and constructive: "This could cause a null pointer if user is 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:

  1. Read each comment carefully
  2. Make the requested changes in new commits (don't force-push during review)
  3. Reply to each comment explaining what you changed or why you disagree
  4. Click "Resolve conversation" once a comment is addressed
  5. Re-request review from the reviewer
tip

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.

Which should you use?

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:

  1. Leave a comment explaining why
  2. 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:

  1. Click the dropdown arrow on "Create pull request"
  2. 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.