Pull requests (PRs) are the central collaboration mechanism on GitHub. They allow you to propose changes, get feedback, run automated checks, and merge code in a controlled, auditable way. Understanding PRs well is one of the most practically important skills for any developer working in a team.
Opening a Pull Request
To open a PR, push a branch to GitHub and then either click the banner GitHub shows ("Compare & pull request") or go to the repository's Pull Requests tab and click "New pull request".
A good PR description should include:
- What: A summary of the changes (1–3 sentences)
- Why: The motivation — what problem does this solve?
- How to test: Steps for reviewers to verify the behaviour
- Screenshots (for UI changes)
- Related issues:
Closes #42orFixes #17
Many teams maintain a PULL_REQUEST_TEMPLATE.md file in .github/ — GitHub pre-populates new PR descriptions with it.
Draft Pull Requests
Open a PR as a draft when you want feedback or want to run CI before the code is ready for full review. Draft PRs cannot be merged. When you are ready, click "Ready for review."
Code Review
Reviewers can leave three types of review:
| Type | Meaning |
|---|---|
| Comment | Feedback without a verdict — questions, suggestions, or FYIs |
| Approve | LGTM — the reviewer is satisfied with the changes |
| Request changes | Blocking — must be addressed before merging |
Giving Good Feedback
- Be specific: reference line numbers, suggest alternatives.
- Distinguish blocking issues from suggestions: use prefixes like
nit:for minor style points. - Be kind: review the code, not the person. Assume good intent.
- Approve when good enough — perfect is the enemy of shipped.
Merge Strategies
GitHub offers three ways to merge a PR — each leaves a different history shape:
| Strategy | Result | Best for |
|---|---|---|
| Merge commit | Creates a merge commit preserving all branch commits | Projects that want full history preserved |
| Squash and merge | Combines all branch commits into one commit on main | Messy WIP commits that should be one logical change |
| Rebase and merge | Replays branch commits on top of main — linear, no merge commit | Teams preferring a clean linear history |
Many teams pick one strategy and enforce it via repository settings so history is consistent.
Branch Protection Rules
Branch protection rules (set in repository Settings → Branches) enforce quality gates on important branches like main:
- Require pull request reviews before merging: Minimum number of approvals required
- Dismiss stale reviews when new commits are pushed: Prevents approving old code and then sneaking in bad commits
- Require status checks to pass: CI must be green before merging
- Require branches to be up to date: Must incorporate latest main before merging
- Restrict who can push to the branch: Only maintainers can push directly
Resolving Conflicts in a PR
If your branch conflicts with the target branch, GitHub will block the merge. Options:
# Update your branch with the latest main by merging
git switch feature/my-feature
git fetch origin
git merge origin/main
# Resolve conflicts, git add, git commit
git push
# Alternatively, rebase onto main
git switch feature/my-feature
git fetch origin
git rebase origin/main
# Resolve conflicts at each step, git add, git rebase --continue
git push --force-with-lease
Use --force-with-lease instead of --force when force-pushing a rebased branch — it refuses to overwrite if someone else has pushed to the remote branch since you last fetched.