Pull requests end to end
Intermediate GitHub UI
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
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.
## 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 #12What, 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:
$ git switch main
$ git pull
$ git branch -d docs/12-windows-install-steps
$ git fetch --pruneremote: 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-stepsIf 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:
$ gh pr create --base main --title "docs: add Windows install steps" --body "Closes #12"The GitHub Pull Requests and Issues extension adds a Pull Requests view: create one from the current branch, read the diff, comment, approve and merge without leaving the editor. It also shows the checks.
With a GitHub account added, the Pull Requests tool window lists them, shows the diff and the checks, and supports reviewing and merging. Git → GitHub → Create Pull Request starts one.
The same object is a merge request, with Overview, Commits, Pipelines and Changes tabs, Closes #12, draft status, approvals and squash options. See lesson 9.7 and the terminology map.
- Push the branch, then use the Compare & pull request banner, or Pull requests → New pull request and set base and compare.
- Write the description: what, why, how to check, and
Closes #N. Use Create draft pull request while it is in progress. - Request Reviewers in the sidebar.
- Watch Checks; open a failing one and read the log.
- Ready for review when it is, then merge with the option your team uses, and Delete branch.
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.
- Create an issue for a small documentation change.
- From the issue's Development section, create a branch;
git fetchandgit switchto it. - Make the change, commit with
(#N)in the message, push. - Open a draft pull request with what, why, how to check, and
Closes #N. Request a reviewer, even yourself. - Mark it ready, merge with Squash and merge, edit the squash message, and Delete branch.
- 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.