Pull Requests — The Core of GitHub Collaboration
What a Pull Request Actually Is
The name "pull request" can be misleading for newcomers. A pull request is not a patch file, not a bundle of commits, and not a request to pull your code blindly. It is a comparison between two branches, presented as a conversation space where code can be reviewed, discussed, and refined before merging.
When you open a PR, you are saying: "Here is the difference between my branch and the target branch. I would like these changes to become part of the target branch. Please review them."
GitHub renders this comparison as a diff — lines removed shown in red, lines added in green — and adds a layer of tooling on top: comments, suggestions, status checks, reviews, and merge controls.
Understanding that a PR is a live comparison (not a snapshot) is important because it means:
- Every new commit you push to your branch automatically updates the PR diff.
- If the target branch advances while your PR is open, the diff shifts — new commits on the target can reduce or increase apparent conflicts.
- A PR is never "submitted and fixed" — it is a living document until it is merged or closed.
Creating a Pull Request
Via GitHub UI
After pushing your branch, navigate to the repository on GitHub. If you pushed recently, you will see a yellow banner: "Your branch had recent pushes. Compare & pull request." Click the button to pre-fill the PR form.
Alternatively, go to the Pull requests tab → New pull request. Select your branch from the compare dropdown and the target branch from the base dropdown.
The PR creation form has these fields:
- Title — one-line summary of what the PR does
- Description — freeform markdown body for detailed explanation
- Reviewers — GitHub users or teams to request review from
- Assignees — who is responsible for this PR (usually yourself)
- Labels — categorization tags
- Projects — link to a project board
- Milestone — link to a milestone
- Linked issues — issues this PR closes or references
Via gh CLI
Writing a Great PR Title
The PR title is the first thing reviewers and maintainers see. A clear title saves everyone time.
The Conventional Commits Pattern
Many teams adopt Conventional Commits for PR titles:
Types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert
The scope is optional — use it when your codebase has clear modules or packages.
Rules for Good PR Titles
- Use the imperative mood: "Add user auth" not "Added user auth" or "Adds user auth"
- Keep it under 72 characters
- Be specific about what the PR does, not how
- Do not just repeat the issue title — add information about the approach
Bad: "Fix bug" Bad: "Implement issue #47" Good: "fix: resolve race condition in concurrent cache writes"
Writing a Great PR Description
The PR description is your opportunity to give reviewers the full context they need to review your changes efficiently. A good description answers:
- What does this PR change?
- Why are these changes being made?
- How was this implemented?
- How can reviewers test or verify the changes?
PR Description Template
Many teams store a PR template at .github/pull_request_template.md. GitHub automatically loads this template when a PR is created:
Create this file in your repository:
Multiple PR Templates
If you need different templates for different kinds of PRs (features vs bug fixes vs release preparations), create a PULL_REQUEST_TEMPLATE/ directory with multiple named templates:
Users access them by adding ?template=feature.md to the PR creation URL — or you can link to them from your CONTRIBUTING.md.
Draft Pull Requests
A draft PR signals that the work is in progress and not ready for review. Reviewers know not to spend time on it yet, but you still get:
- Continuous integration checks running on every push
- The ability to request early feedback on specific parts
- A visible record of work-in-progress
- Automated status checks running
Creating a Draft PR
Marking a Draft PR Ready for Review
When your work is complete:
Draft PRs are widely used for:
- Starting a PR early to get CI running from the beginning
- Requesting early architectural feedback before polishing the implementation
- Sharing work-in-progress with collaborators who need to see the direction
- Work that is blocked on another PR or external dependency
Linked Issues
Linking issues to PRs creates a clear trail from reported problem to implemented solution. GitHub tracks these relationships and displays them on both the PR and the issue.
Issue Closing Keywords
Certain keywords in a PR title, description, or commit message will automatically close the linked issue when the PR is merged into the default branch:
You can link multiple issues:
You can also link to issues in other repositories:
Referencing Without Closing
To reference an issue without closing it when the PR merges:
PR Review Process Overview
Once a PR is open and marked ready for review, the review process begins. The full review workflow is covered in lesson 4, but here is the high-level overview:
- Reviewers receive a notification (email, GitHub inbox, Slack integration, etc.)
- Reviewers examine the diff, leave inline comments on specific lines, and optionally start a formal review
- The reviewer submits their review with one of three verdicts: Approve, Request Changes, or Comment
- The PR author addresses feedback by pushing new commits or responding to comments
- If changes were requested, reviewers re-review and either approve or request further changes
- Once all required reviews are approved and status checks pass, the PR can be merged
Resolving Conversations
When a reviewer leaves a comment on a specific line, it creates a "conversation" on that line. Conversations can be:
- Replied to — continue the discussion
- Resolved — marked as addressed. Either the reviewer or the PR author can mark a conversation resolved.
Conventions vary by team, but a common pattern is: the PR author resolves conversations after addressing the feedback, and reviewers can re-open if they feel the feedback wasn't addressed.
The PR page shows a "Conversations" count in the header. PRs with unresolved conversations cannot be merged if the repository has branch protection rules requiring "all conversations to be resolved before merging."
Merge Strategies
When a PR is approved and ready, there are three ways to merge it. The merge strategy affects the shape of the resulting Git history.
Merge Commit (Create a Merge Commit)
The merge commit G records that commits D, E, F from feature were merged into main at point C. The full branch history is preserved.
When to use: When you want to preserve the complete history of feature development, including intermediate commits. Common in projects that value a detailed audit trail.
Squash and Merge
All commits from the feature branch are squashed into a single new commit on main. The feature branch's intermediate commits are not present in main's history.
When to use: When feature branch commits are messy (lots of "WIP", "fix typo", "try again" commits) and you want a clean, readable main history. Each PR becomes one commit in main. This is the most popular strategy for application development.
Rebase and Merge
Each commit from the feature branch is replayed on top of main. The commits get new SHAs (D', E', F') because their parent has changed, but no merge commit is created. Linear history is maintained.
When to use: When you want to preserve individual commits (unlike squash) and also want a linear history (unlike merge commit). Common in projects that use Conventional Commits — each commit carries semantic meaning.
Configuring the Allowed Strategies
Repository admins can restrict which merge strategies are available:
Settings → General → scroll to Pull Requests section → uncheck the strategies you don't want to allow.
Which Should You Use?
| Strategy | History | Commit Count | Traceability | |----------|---------|--------------|--------------| | Merge commit | Non-linear | Preserves all | Full branch preserved | | Squash | Linear | One per PR | Good (via PR link) | | Rebase | Linear | Preserves all | Individual commits |
Most teams choose squash and merge as the default because it produces readable linear history while keeping individual PR history in the PR page (which is searchable on GitHub). The feature branch details are always accessible via the PR link in the squashed commit message.
Auto-Merge
Auto-merge allows you to pre-authorize a merge that will execute automatically once all required conditions are met: all required reviewers have approved, all required status checks have passed, and any other branch protection rules are satisfied.
Enabling Auto-Merge
Repository admins must enable the feature first:
Settings → General → Pull Requests → check Allow auto-merge
Activating Auto-Merge on a PR
Auto-merge is useful for:
- PRs that are approved but waiting for a long-running CI pipeline
- Dependency update PRs (Dependabot) that you want to merge as soon as CI passes
- Low-risk changes that don't need synchronous attention to merge
If new commits are pushed to the PR after enabling auto-merge (e.g., a reviewer requests changes), auto-merge is disabled and must be re-enabled after the changes are addressed.
Closing PRs
Merging
Once approved and checks pass, click Merge pull request and choose your merge strategy. The PR moves to the "Merged" state — shown with a purple icon.
Closing Without Merging
If a PR is no longer needed — the approach was abandoned, someone else solved the problem differently, the issue is no longer relevant — close it without merging by clicking Close pull request. The PR moves to the "Closed" state — shown with a red icon.
Provide a comment explaining why the PR is being closed without merging. This is respectful to the contributor and provides useful context for anyone who finds the PR later.
Reopening
Closed PRs (not merged, just closed) can be reopened as long as the source branch still exists. Click Reopen pull request on the closed PR page.
PR Best Practices
Keep PRs Small
Large PRs are harder to review, take longer to get approved, have more merge conflicts, and are riskier to merge. Aim for PRs that:
- Make one logical change (not one file, not one day's work)
- Can be reviewed in 15-30 minutes
- Have fewer than 400 lines of diff (excluding generated files)
If a feature requires large changes, break it into a stack of sequential PRs, each building on the previous.
Use a Consistent Branch Off Main
Avoid creating branches off other feature branches unless you intentionally need to (stacked PRs). Branching off main keeps things simple and reduces the risk of bringing in uncommitted or unstable changes.
Update the PR If the Description Changes
If your implementation changes significantly during review, update the PR description. Reviewers sometimes re-read the description when re-reviewing — it should accurately reflect what the PR actually does.
Respond to Every Comment
Even if you disagree with feedback, respond. "Addressed in latest commit" or "I think X is better here because Y — open to further discussion" are both better than silence. Unresponsive PRs get closed.
Practical Exercises
Exercise 1 — Create a PR with a Full Description
- In a practice repository, create a branch, make a meaningful change, and push it.
- Open a PR with a title following Conventional Commits format.
- Write a full description using the template structure: Summary, Changes, Testing, Related Issues.
- Add yourself as the assignee and apply an appropriate label.
Exercise 2 — Draft PR Workflow
- Create a branch with some incomplete work (it doesn't need to compile or pass tests).
- Open a draft PR for this branch.
- Make two additional commits to the branch — observe that the PR updates automatically.
- Mark the PR ready for review.
Exercise 3 — Compare Merge Strategies
- Create a repository with a
mainbranch that has 3 commits. - Create a feature branch with 3 commits.
- Merge it three times using different strategies (use three separate feature branches with the same changes).
- Use
git log --oneline --graphto compare the resulting histories.
Exercise 4 — Closing Keywords
- Create an issue in your repository.
- Open a PR and include "Closes #1" (or whatever the issue number is) in the description.
- Merge the PR.
- Verify that the issue was automatically closed.
- Open the issue and notice the "closed by" link to the PR.
Exercise 5 — Auto-Merge
- Enable auto-merge in a repository's Settings.
- Open a PR and enable auto-merge on it.
- Add a reviewer (or approve it yourself in a personal repo).
- Observe the PR auto-merge when all conditions are met.