Stage 2 · Tools
Remote Collaboration
Pull Requests & Code Review
PR workflow, review etiquette, squash vs merge, and keeping history clean.
The PR Workflow
Pull requests are the primary mechanism for code review in modern teams. The standard flow is: create a branch, make commits, push the branch, open a PR, get review approval, and merge. This workflow enables discussion, automated testing, and quality gates before code enters the main branch.
- Create a feature branch from main
- Make focused, atomic commits
- Push the branch to the remote
- Open a pull request with a clear description
- Address review feedback
- Merge once approved and CI passes
Pull requests serve as documentation, discussion threads, CI checkpoints, and audit trails. A well-written PR description explains the *why* behind changes, not just the *what*.
Creating Pull Requests
GitHub CLI (gh) lets you create PRs from the terminal without opening a browser. This integrates well with keyboard-driven workflows and automation scripts.
gh pr create \
--base main \
--head feature/user-auth \
--title "Add JWT authentication" \
--body "## Changes
- Added login endpoint
- JWT token generation
- Middleware for protected routes
## Testing
- Unit tests for token generation
- Integration test for login flow
Closes #42"Creates a PR from feature/user-auth into main. The --body supports Markdown for formatting. The Closes #42 keyword auto-closes the linked issue on merge.
gh pr create --draft --title "WIP: payment integration" --body "Working on Stripe integration"Draft PRs signal that the work is in progress and not ready for full review. Reviewers know they can provide early feedback but shouldn't do a thorough review yet.
gh pr list
gh pr checkout 123Lists open PRs and checks out PR #123 as a local branch. Useful for testing the changes locally before reviewing.
Good PR titles describe the change concisely: "Add rate limiting to API endpoints" not "Update files". Reviewers scan titles to prioritize reviews.
Merge Strategies
When a PR is approved, you need to merge it. GitHub offers three merge strategies, each producing different history. The choice affects readability, traceability, and ease of reverting.
| Strategy | History shape | When to use |
|---|---|---|
| Merge commit | Preserves branch topology with a merge commit | Feature branches with meaningful context |
| Squash and merge | Single commit on main, discards branch history | Small PRs with noisy or intermediate commits |
| Rebase and merge | Linear history, individual commits replayed on main | Clean linear history with meaningful individual commits |
gh pr merge 123 --merge
gh pr merge 123 --squash
gh pr merge 123 --rebaseEach flag selects the merge strategy. Choose based on your team's history preference. Squash is most common for feature branches with many small commits.
Squashing combines all PR commits into one. This is clean for main, but you lose the step-by-step history of how the change evolved. For large features, consider keeping merge commits to preserve context.
Code Review Etiquette
Code review is a collaboration, not a gatekeeping exercise. Both the author and reviewer share responsibility for making the process productive.
As an author:
- Write a clear PR description explaining the context and approach
- Keep PRs focused — one concern per PR
- Respond to feedback gracefully, even when you disagree
- Mark resolved conversations to help reviewers track progress
- Self-review your diff before requesting reviews
As a reviewer:
- Review promptly — delays block your teammates
- Focus on correctness, design, and maintainability over style
- Distinguish between blocking issues and suggestions
- Ask questions instead of making demands: "What happens if...?"
- Praise good patterns and creative solutions
gh pr diff 123
gh pr view 123
gh pr review 123 --approve --body "LGTM, nice refactor on the auth flow"View the diff, see the full PR description, and submit a review with comments — all from the terminal.
Automate style enforcement with linters and formatters. Reserve human review for logic, architecture, and design decisions. Arguments about semicolons waste everyone's time.
Keeping PRs Small
Large PRs are hard to review, easy to miss bugs in, and slow to get approved. Research and practice consistently show that smaller PRs — under 400 lines of changes — get reviewed faster, have fewer defects, and lead to better discussions.
| PR Size | Review time | Defect rate | Review quality |
|---|---|---|---|
| < 100 lines | < 1 hour | Low | Thorough |
| 100–400 lines | 1–4 hours | Moderate | Good |
| > 400 lines | 1+ days | High | Surface-level |
Strategies for keeping PRs small:
- Break features into vertical slices (one model + view + test per PR)
- Use stacked PRs for large features
- Refactor first, then add features on clean code
- Use draft PRs to get early feedback on large changes
- Extract shared utilities into separate prerequisite PRs
For a feature requiring 1000+ lines, create a chain: PR 1 adds the data model, PR 2 adds the API, PR 3 adds the UI. Each PR is small, reviewable, and mergeable independently.
CODEOWNERS
CODEOWNERS is a file that defines who is responsible for which parts of the codebase. When a PR touches files matching a CODEOWNERS pattern, those owners are automatically requested for review.
# Global default
* @myorg/engineering-leads
# Frontend
/src/components/ @myorg/frontend-team
/src/styles/ @myorg/design-team
# Backend
/api/ @myorg/backend-team
/migrations/ @myorg/database-admins
# Infrastructure
/Dockerfile @myorg/devops
/docker-compose @myorg/devops
*.tf @myorg/platform-teamPlace this file in .github/CODEOWNERS, docs/CODEOWNERS, or the repo root. Patterns are matched last-wins, so more specific rules override general ones.
gh api repos/{owner}/{repo}/codeowners --jq '.owners[] | select(.path == "src/components/Button.tsx")'Queries the GitHub API to see which team or user owns a specific file. Useful for finding the right reviewer when CODEOWNERS is complex.
Set branch protection rules to require reviews from CODEOWNERS. This ensures the right people always review changes to critical code paths.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.