Git Course 0%

Pull requests end to end

Intermediate GitHub UI ≈ 18 min

What you will learn

  • How to open a pull request, including from a fork
  • What each tab and sidebar field is for
  • Why the merge button is blocked, and which merge option to choose

After this lesson you can

  • I can take a pull request from creation to merged without being told what to do

Why this matters

The pull request is where your work meets the team, and it is the page you will spend the most time on. It is also the same object as GitLab's merge request under a different name, so if you know one, this lesson is mostly renaming.

The life of one

The life of a pull request Seven stages left to right: push a branch, open the pull request as a draft, checks run in Actions, review on the Files changed tab, push fixes and reply, which loops back to the checks, approval, and merge with the branch deleted. Below, the conditions that unlock the merge button: not a draft, required checks passing, required reviews approved, no requested changes outstanding, conversations resolved if the repository requires it, and no conflicts. A note says the three merge buttons are create a merge commit, squash and merge, and rebase and merge, and that writing Closes with an issue number closes the issue at merge. Push thebranch Open the PRas a draft Checks runActions ReviewFiles changed Push fixesand reply Approve Mergedelete branch every push re-runs the checks and updates the pull request The merge button unlocks only when all of these are true not a draft · checks green · required reviews approved · no blocking review · no conflicts Three merge buttons: create a merge commit, squash and merge, rebase and merge. "Closes #12" in the description closes the issue at merge, exactly as on GitLab.
Push, open as a draft, checks run, review, fixes, approval, merge with the branch deleted.

Opening one

Route How Pre-fills
After a push The push output prints a URL; the repository page shows a Compare & pull request banner The source branch
From the list Pull requests → New pull request, then choose base and compare branches Nothing
From an issue The issue's Development section creates a branch; the pull request from it links back The branch name
From a fork The same New pull request, with the base being the upstream repository Nothing

The words to keep straight: base is where the change is going, usually main; compare is your branch. Getting them the wrong way round produces a pull request proposing to undo everything, which is alarming and harmless.

For a fork, GitHub adds Allow edits by maintainers, ticked by default. Leave it on: it lets a maintainer push a small fix to your branch instead of asking you for it (lesson 7.7).

Writing the description

The diff says what changed. The description says why, and it is read by the reviewer now and by whoever investigates in a year.

Markdown
## What

Adds the Windows steps to the installation guide, and links them from the FAQ.

## Why

Support gets this question weekly; issue #12 has three examples.

## How to check

Read `docs/getting-started.md` on this branch, or the preview built by the docs check.

Closes #12

What, why, how to verify, and the closing keyword. If the repository has a template at .github/pull_request_template.md, the box arrives pre-filled; fill in the headings rather than deleting them.

Draft pull requests are the other half. Create draft pull request opens one that cannot be merged and does not request reviews, which is how you say "look, but do not merge". Ready for review converts it. Opening as a draft early is good practice: the checks run and colleagues see the direction.

The page

Tab Shows
Conversation The description, comments, reviews, checks summary and the merge box
Commits The commits your branch adds
Checks Each workflow run and its logs (lesson 10.10)
Files changed The diff, where reviews are written (lesson 10.8)

The sidebar carries Reviewers (requesting one sends them a notification and a review request, which is the correct way to ask), Assignees (who is responsible for moving it forward), Labels, Projects, Milestone and Development, which links the issue this closes.

Checks and the merge box

The merge box at the bottom of Conversation tells you exactly what is missing:

Message Meaning Fix
Still in progress? (draft) It is a draft Ready for review
Some checks were not successful A required check failed Open Checks, read the failing job
Review required The rules require approvals Request a reviewer
Changes requested A reviewer blocked it Address the comments, then re-request review
This branch is out-of-date with the base branch The rule requires up-to-date branches Update branch
This branch has conflicts Your change and the base disagree Resolve (Section 11)
All checks have passed Nothing is missing Merge

Update branch offers two ways to bring main in: a merge commit or a rebase. Merge is the safe default and adds a commit; rebase rewrites your branch's commits, which is fine for a branch only you use (lesson 6.7).

The three merge buttons

Option Result on main Use when
Create a merge commit Every commit of your branch, plus a merge commit The individual commits are meaningful
Squash and merge One commit containing all your changes The usual choice; the branch was a work in progress
Rebase and merge Your commits replayed on top, no merge commit The team wants a straight line and the commits are clean

Which are available is a repository setting, so a team may offer only one. Squash and merge is the most common default and the friendliest for the sort of branch that accumulates "fix typo" commits; the squash commit's message is editable, so write a good one.

After merging, Delete branch appears; take it. Your local repository knows none of this until you catch up:

Terminal
$ git switch main
$ git pull
$ git branch -d docs/12-windows-install-steps
$ git fetch --prune
remote: Create a pull request for 'docs/12-windows-install-steps' on GitHub by visiting:
remote:      https://github.com/northwind-trails/trailguide/pull/new/docs/12-windows-install-steps

If something turns out to be wrong, the merged pull request has a Revert button that opens a new pull request undoing it, which is the safe way to back a change out (lesson 5.6).

How to do it

The terminal makes the branch and the commits; the pull request is GitHub's. The push prints the link:

With GitHub's gh tool installed, the whole thing is one command:

Terminal
$ gh pr create --base main --title "docs: add Windows install steps" --body "Closes #12"

Common mistakes

  • Base and compare the wrong way round, producing a pull request that proposes deleting everything.
  • An empty description, leaving the reviewer to reconstruct the reason from the diff.
  • Forgetting Closes #N, so the issue stays open after the work ships.
  • Leaving it as a draft while waiting for a review nobody knows is wanted.
  • Mentioning a reviewer in a comment instead of requesting a review.
  • Accepting the default squash message, which is often a list of "wip" commits.
  • Leaving the branch behind after merging.

Try it yourself

Goal: run one from issue to merged on your own repository.

  1. Create an issue for a small documentation change.
  2. From the issue's Development section, create a branch; git fetch and git switch to it.
  3. Make the change, commit with (#N) in the message, push.
  4. Open a draft pull request with what, why, how to check, and Closes #N. Request a reviewer, even yourself.
  5. Mark it ready, merge with Squash and merge, edit the squash message, and Delete branch.
  6. Locally: git switch main, git pull, git fetch --prune, and confirm the issue closed.

Expected result: the issue is closed, main has one clean commit, the branch is gone in both places, and the pull request records the whole story.

Show solution

Step 6 tests the description: if the issue is still open, Closes #N was missing or misspelled, and editing the description afterwards does not close it retroactively. Squash message editing in step 5 matters too, because that message is what git log on main will show forever.

Check yourself

1. On a new pull request, what are "base" and "compare"?
2. Which merge option puts a single commit on main no matter how many commits your branch had?
3. A reviewer must look at your work. What is the correct action?

Key terms

Pull request (PR) Branch Squash Code review Protected branch