Pull Requests and Code Review
A pull request (PR) — called a merge request on GitLab — is a proposal to merge one branch into another, hosted on a site like GitHub. It shows the changes, runs automated checks, and gives teammates a place to review and discuss before anything reaches main. It's how most teams and open-source projects accept code.
The workflow at a glance
- Update
mainand create a branch for the change. - Commit your work and push the branch.
- Open a pull request on GitHub from your branch into
main. - Automated checks run; teammates review and comment.
- Push more commits to the same branch to address feedback — the PR updates itself.
- Once approved, merge the PR on GitHub, then delete the branch.
- Locally, switch back to
mainand pull.
1–2. Branch, commit, push
git switch main git pull git switch -c feature/discount-codes
Already on 'main' Your branch is up to date with 'origin/main'. Already up to date. Switched to a new branch 'feature/discount-codes'
printf 'function total(items, discount = 0) {\n const sum = items.reduce((s, i) => s + i.price, 0);\n return sum * (1 - discount);\n}\n' > basket.js git commit -am "Apply discount codes to basket total" git push -u origin feature/discount-codes
[feature/discount-codes 0568c86] Apply discount codes to basket total 1 file changed, 3 insertions(+), 2 deletions(-) Enumerating objects: 5, done. Counting objects: 100% (5/5), done. Delta compression using up to 10 threads Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 357 bytes | 357.00 KiB/s, done. Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 To https://github.com/sam-rivera/shop.git * [new branch] feature/discount-codes -> feature/discount-codes branch 'feature/discount-codes' set up to track 'origin/feature/discount-codes'.
On GitHub, the push output also contains a remote: line with a link to create a pull request for the new branch, and the repository page shows a "Compare & pull request" button.
3. Opening the pull request
On the PR form, choose the base branch (where the changes should go, usually main) and the compare branch (yours). Then write:
- A title that summarises the change, like a good commit summary.
- A description: what changed and why, how to test it, screenshots for visual changes, and links to issues (
Closes #57closes the issue when the PR merges).
If the work isn't finished but you want early feedback, open it as a draft pull request. With the GitHub CLI you can do all of this from the terminal:
gh pr create --base main --title "Apply discount codes to basket total" --body "Closes #57" gh pr view --web # open it in the browser
4. Review
Reviewers read the Files changed tab, leave comments on specific lines, and finish with one of: Comment, Approve or Request changes. Meanwhile automated checks (tests, linting, builds — often GitHub Actions) report a green tick or red cross on the PR.
Good reviews are about the code, not the person: ask questions, explain the reason behind a suggestion, and separate must-fix issues from optional nitpicks. As an author, keep PRs small — a few hundred lines at most — so they can be reviewed properly.
5. Responding to feedback
A reviewer points out that a discount above 100% would make the total negative. Sam fixes it on the same branch and pushes; the new commit appears in the PR automatically:
printf 'function total(items, discount = 0) {\n const sum = items.reduce((s, i) => s + i.price, 0);\n const rate = Math.min(Math.max(discount, 0), 1);\n return sum * (1 - rate);\n}\n' > basket.js git commit -am "Clamp discount between 0 and 100%" git push
[feature/discount-codes 97b131d] Clamp discount between 0 and 100% 1 file changed, 2 insertions(+), 1 deletion(-) Enumerating objects: 5, done. Counting objects: 100% (5/5), done. Delta compression using up to 10 threads Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 382 bytes | 382.00 KiB/s, done. Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 To https://github.com/sam-rivera/shop.git 0568c86..97b131d feature/discount-codes -> feature/discount-codes
If main has moved on and your PR now conflicts, update your branch: merge main into it, or rebase it onto main and push with --force-with-lease. GitHub's "Update branch" button does the merge version for you.
6. Merging the pull request
GitHub offers three merge buttons; repository settings decide which are allowed:
| Option | What lands on main | Good for |
|---|---|---|
| Create a merge commit | All the branch's commits plus a merge commit | Keeping the full detail of how the work evolved |
| Squash and merge | One new commit containing all the changes | A clean main with one commit per PR, hiding "fix typo" commits |
| Rebase and merge | Each commit replayed onto main, no merge commit | Linear history when every commit is already tidy |
After merging, GitHub offers a "Delete branch" button (or deletes it automatically if the repository is set up to).
7. Cleaning up locally
The PR was merged with a merge commit and the branch deleted on GitHub. Sam brings main up to date and removes the local branch:
git switch main git pull --prune
Switched to branch 'main' Your branch is up to date with 'origin/main'. From https://github.com/sam-rivera/shop - [deleted] (none) -> origin/feature/discount-codes remote: Enumerating objects: 1, done. remote: Counting objects: 100% (1/1), done. remote: Total 1 (delta 0), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (1/1), 228 bytes | 228.00 KiB/s, done. 471a8db..e2cc0e0 main -> origin/main Updating 471a8db..e2cc0e0 Fast-forward basket.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
git branch -d feature/discount-codes git log --oneline --graph
Deleted branch feature/discount-codes (was 97b131d). * e2cc0e0 (HEAD -> main, origin/main, origin/HEAD) Merge pull request #58 from sam-rivera/feature/discount-codes |\ | * 97b131d Clamp discount between 0 and 100% | * 0568c86 Apply discount codes to basket total |/ * 471a8db Add basket total
If the PR had been squash-merged, git branch -d would refuse with "not fully merged": the squash created a new commit, so Git can't tell your branch's commits are in main. Check the PR is merged, then delete with -D.
Protecting main
Repository admins can add branch protection rules (or rulesets) on GitHub so that main can only change through pull requests: requiring approvals, passing checks, an up-to-date branch, and blocking force pushes. A CODEOWNERS file can automatically request reviews from the people responsible for particular folders.
Try it yourself
In a repository you own on GitHub, make a branch, push a change and open a pull request. Add a comment on one line of your own diff, push a follow-up commit, then merge with "Squash and merge". Finally update your local main and delete the branch locally with -D.