6.2 Pull Requests

Key Takeaways

  • A pull request is a proposal to merge a head branch into a base branch so reviewers can discuss the change before it lands.
  • GitHub organizes a pull request into Conversation, Commits, Checks, and Files changed tabs; a Findings tab may show automated review such as code scanning, and the merge box shows blockers separately from those tabs.
  • Draft pull requests cannot be merged, and CODEOWNERS are not automatically requested until the draft is marked ready for review.
  • Fork-and-pull lets anyone with read access (when forking is allowed) push to their own fork and open a pull request on the upstream repository; the shared-repository model uses topic branches inside one repo that collaborators can push to.
  • Reviewers submit Comment, Approve, or Request changes; maintainers with write access then merge with a merge commit, squash and merge, or rebase and merge depending on how the team wants history to look.
Last updated: August 2026

Why pull requests are GitHub's key collaboration feature

After issues, GH-900 asks you to describe how to use pull requests. GitHub's About pull requests definition is the one to memorize: a pull request is a proposal to merge code (or any files) into a project so people can discuss and review changes before merging. Domain 1 already taught GitHub Flow—branch, commit, open a PR, review, merge, delete the branch. This Domain 3 skill is the product surface of that PR: the tabs, draft state, collaboration model, review outcomes, and merge methods.

A pull request always has a head (the branch that contains the work) and a base (the branch that will receive the work). On github.com the default base is usually the repository default branch (commonly main). Opening a PR does not change the base branch. GitHub creates temporary refs that point at the head and, when possible, at a simulated merge result so checks can run without touching main.

You need write permission on the repository to merge. Opening a pull request from a fork does not require write on the upstream repository; that is the point of the fork-and-pull model below.

The pull request tabs

GitHub groups the context reviewers need into tabs. Name them; GH-900 loves "which tab shows X?"

TabWhat you seeWhy it exists
ConversationDescription, timeline, comments, submitted reviewsThe human discussion and the decision record
CommitsEach commit on the pull request branch, in orderHow the head branch evolved; useful when commits are meaningful
ChecksAutomated tests, builds, and other status checksCI and required checks that can block merge
Files changedThe diff reviewers annotateThe actual proposed change
FindingsAutomated review such as code scanning alerts on the proposed changesSecurity and quality findings tied to this PR

The merge status is not a fifth classic study-guide tab. It sits in the pull request header and in the merge box: missing approvals, failing checks, conflicts, draft state, and other blockers. Do not say "look on Commits to see if you can merge." Merge-readiness lives in the merge box.

Compare pages and pull request pages can show different diffs because they may choose different merge bases. If main moved after the PR opened, the PR page focuses on what the PR introduced; a compare view of two refs shows the current gap. That detail is easy to over-study. The exam-level point is: the Files changed tab on the pull request is the review surface, not a random compare URL.

Line comments and suggested changes live on Files changed and then appear in Conversation. A review is not complete until the reviewer submits it; pending comments are visible only to that reviewer.

Draft pull requests

When you create a pull request you can open it as a draft. GitHub is explicit:

  • A draft cannot be merged.
  • Code owners are not automatically requested to review a draft.
  • Drafts exist so you can share work-in-progress without formally requesting reviews.
  • When you mark it ready for review, GitHub requests reviews from any code owners.
  • You can convert a ready pull request back to a draft at any time. People already subscribed to notifications are not automatically unsubscribed.

Search with draft:true or draft:false. A required-review branch protection rule still sees a draft as not mergeable; marking ready is what starts the real review clock. Exam trap: "drafts hide the pull request." They do not. They change mergeability and CODEOWNERS auto-request behavior.

Fork-and-pull versus shared repository

How you open pull requests depends on the collaborative development model.

Fork and pull

In the fork-and-pull model, anyone with read access can fork the upstream repository if the owner allows forks. You push to your fork, then open a pull request from your fork's branch to the upstream base branch. You do not need permission from upstream to push to your fork. Maintainers review and merge in the upstream repository. This is the default open-source pattern: low friction for first-time contributors, no write access on the canonical repo.

Optional upstream setting: allow people with push access on upstream to push commits onto your pull request branch ("Allow edits from maintainers"). That lets a maintainer fix a small CI miss without blocking on the contributor.

GitHub notes that a fork and its upstream share Git objects. Content you push to a fork is reachable from the upstream network. Do not treat a fork of a public project as a private vault.

Shared repository

In the shared repository model, collaborators already have push access to one repository. They create topic branches and open pull requests in that same repository. The PR is still the review and discussion step before merging into the main development branch. This is typical of small teams and private organization projects where everyone is already a collaborator.

QuestionFork and pullShared repository
Where do you push?Your forkA topic branch in the shared repo
Do you need write on the canonical repo to propose a change?No (read + fork)Yes, at least push on a branch
Typical homePublic open sourcePrivate teams
Pull request still used?Yes, into upstreamYes, into the default or other base branch

GH-900 will give you a one-line story. "External contributor, no write, public repo" is fork-and-pull. "Five teammates, all have push, private product repo" is shared-repository. Pull requests exist in both; the difference is where the head branch lives.

Loading diagram...
Pull request collaboration: two models, one review gate

Reviews: Comment, Approve, Request changes

Pull request reviews let people comment on changes, suggest exact edits, and then submit one of three review decisions:

DecisionMeaning
CommentGeneral feedback; does not approve and does not request changes
ApproveThe changes are ready to merge from this reviewer's point of view
Request changesThe author should address the feedback before merging

Anyone with read access can review and comment. Requesting a review is stricter: you need write access (pull request authors who are owners or write collaborators can request; organization members with write or triage can also assign a reviewer). You can request a person or a team who has at least read access; they get a notification. If you request a team and code review assignment is enabled, GitHub requests specific members and removes the team as the reviewer.

CODEOWNERS automatically request review when a pull request (that is not a draft) touches owned paths. Administrators can add a branch protection or ruleset requirement that a pull request must be approved by a code owner before merge. Required reviews are a protection feature; they are not automatic on every public repository.

Exam traps on reviews:

  • Comment is a real submitted review. It is not a failed approval.
  • Request changes is not a merge. It is a blocker when reviews are required.
  • A read-only outsider can leave a review on a public repository; they cannot merge.
  • Assigning someone as assignee does not request their review. Reviewers and assignees are different sidebar fields (section 6.3).

Merge methods at conceptual depth

With write permission, and with the repository allowing the method, you pick how history should look. GitHub's merge docs are the source.

Merge commit

The default Merge pull request action adds all commits from the feature branch onto the base plus an explicit merge commit. GitHub uses git merge --no-ff. You keep the full topic-branch history and a visible merge point. Choose this when individual commits are meaningful or the team wants to see exactly when a branch joined main.

Squash and merge

Squash and merge combines every commit on the pull request into one commit on the base branch (fast-forward of that single squashed commit). Work-in-progress fixups disappear from default-branch history. Choose this when the PR is one logical change and the branch is noisy. The repository must allow squash merging. GitHub generates a default squash message you can edit; administrators configure whether that default includes the PR title, description, or commit list.

Squash is a poor fit for a long-running branch you keep reusing. Later pull requests from that same head can reintroduce already-squashed commits and replay conflicts. After a squash merge, delete the branch (GitHub Flow) and start fresh.

Rebase and merge

Rebase and merge replays each topic-branch commit onto the base without a merge commit, producing a linear history. GitHub always rewrites committer information and creates new SHAs, even in cases where local git rebase would not. It also drops originally empty commits (git commit --allow-empty), which local rebase keeps by default. If GitHub cannot rebase cleanly, you rebase locally, resolve conflicts, push, and try again. Choose rebase when commits are already clean and the team wants linear history without a merge bubble.

MethodWhat lands on the base branchHistory shapeTypical reason to choose it
Merge commitAll PR commits + a merge commitNon-linear; merge nodePreserve complete history
Squash and mergeOne combined commitLinear, compactOne PR = one logical change
Rebase and mergeEach PR commit, new SHAs, no merge commitLinear, detailedClean commits, no merge commit

Indirect merges exist: if the head commits become reachable from the base through another path (another PR or a direct push), GitHub can mark this PR merged even if this PR's protection rules were not satisfied. Uncommon, but it explains a PR that shows merged when nobody pressed the button on that page.

Exam scenarios and traps

  • "Share WIP without requesting code owners" → draft pull request, not a secret branch nobody can see.
  • "Outside contributor, public repo" → fork-and-pull. "Internal team with push" → shared repository. Both still use pull requests.
  • Files changed is the diff. Conversation is the discussion. Checks are CI. Commits are the list of commits. Do not mix them.
  • Squash is not "delete Git history of the repository." It is one commit on the base branch for that PR.
  • Rebase-and-merge on GitHub is not identical to local git rebase (new SHAs, dropped empty commits).
  • You cannot merge a draft. Marking ready both enables merge (subject to protections) and requests CODEOWNERS.
  • Merge requires write. Review requires read. Requesting a reviewer requires write (or triage, for assigning a reviewer on an org repo).

If you can walk a PR from draft to submitted review to a chosen merge method, and you can say whether the head branch lived in a fork or in the same repo, you have the Domain 3 pull request skill.

Test Your Knowledge

What is true of a draft pull request on GitHub?

A
B
C
D
Test Your Knowledge

An outside contributor has read access to a public repository but not write access. How do they propose a change with a pull request?

A
B
C
D
Test Your Knowledge

A team wants default-branch history to stay linear and wants each reviewed commit on a short-lived pull request preserved, not folded into one commit. Which merge method matches that goal?

A
B
C
D