A pull request (PR) is a request to merge the commits on one branch into another, paused so a teammate can review them before they land. You create one by pushing a branch to the remote, then opening the PR in GitHub or GitLab and choosing what to merge into what. The whole loop is: make a branch, commit, push, open the PR, request review, address feedback, merge.
On GitLab the same thing is called a "merge request" (MR). The mechanics are identical; only the name differs. I will use "pull request" throughout and point out the GitLab wording where it matters.
If branches and remotes are still new to you, the Git for beginners guide is the place to start, and Git branching explained covers the branch model this whole workflow sits on.
The short version
# 1. start a branch off the up-to-date main
git switch -c add-login-page
# 2. do the work, then stage and commit
git add .
git commit -m "Add login page and form validation"
# 3. push the branch and set its upstream
git push -u origin add-login-pageAfter that last push, GitHub prints a URL in the terminal that opens the "create pull request" form prefilled with your branch. Click it, write a description, hit "Create pull request", and you are done with the hard part.
Step 1: branch off an up-to-date main
Never open a pull request from main itself. The point of a PR is to compare a feature branch against the base, so the work needs to live on its own branch. Before you branch, pull the latest base so your branch starts from current code (if you are fuzzy on what pull actually does versus a fetch, git pull vs git fetch clears it up):
git switch main
git pull
git switch -c add-login-pagegit switch -c creates the branch and moves you onto it in one step. Name it for the work, not for yourself: add-login-page, fix-timezone-bug, bump-node-20. If you are on an older Git, git checkout -b add-login-page does the same thing. For more on starting clean branches, see Git branching explained for beginners.
Step 2: commit your work
Stage the changes and commit them. If you are unsure what git add actually does, the staging area explained walks through it.
git add .
git commit -m "Add login page and form validation"A pull request is only as readable as its commits, so write real messages, not "wip" or "stuff". My take on commit message conventions has the format I use. You can commit as many times as you like on the branch; reviewers see the full history, and you can tidy it later with an interactive rebase squash if the branch got noisy.
Step 3: push the branch to the remote
The branch only exists on your machine until you push it. The first push needs -u (short for --set-upstream) to link your local branch to a remote one:
git push -u origin add-login-pageIf you skip the -u and just run git push, you will hit this:
fatal: The current branch add-login-page has no upstream branch.That is a one-line fix, covered in the no upstream branch guide. After the first -u push, plain git push works for the rest of the branch's life.
If the push itself is rejected, the failed to push some refs fix covers the common causes (the remote has commits you do not). For the SSH-key prompt that some setups throw on first push, adding an SSH key to GitHub sorts it out; if you have not decided whether to use SSH instead of HTTPS for the remote in the first place, settle that before your first push.
Step 4: open the pull request
Now you leave the terminal. There are three ways to get to the PR form.
From the terminal URL. GitHub prints a "Create a pull request" link right after the push. Paste it into the browser and the form is prefilled.
From the repo page. GitHub shows a yellow "Compare & pull request" banner for any recently pushed branch. Click it.
Manually. Go to the repo, click the "Pull requests" tab, then "New pull request", and pick your branch in the "compare" dropdown.
Either way you land on the compare view, which has two dropdowns at the top:
base: main <- compare: add-login-pagebase is where your work will merge into (usually main). compare is your branch. Getting these backwards is the single most common beginner mistake: if the diff looks empty or shows the wrong commits, you have the base and compare swapped.
On GitLab, the path is the project's "Merge requests" section, then "New merge request", then pick the source branch (yours) and the target branch (main). Same two-dropdown idea, mirrored wording: GitLab calls them "source" and "target".
Step 5: write a description that respects the reviewer
The title and body are not paperwork. They are what decides how fast and how well your PR gets reviewed. A good description answers three questions before the reviewer has to ask:
- What does this change? One or two plain sentences.
- Why? The problem it solves, or a link to the issue (
Closes #142auto-closes the issue on merge). - How do I check it? The steps to test, or what to look at.
A workable template:
## What
Adds the login page and client-side form validation.
## Why
Closes #142. Users had no way to sign in from the marketing site.
## How to test
1. Run the app, visit /login
2. Submit empty form -> see inline errors
3. Submit valid creds -> redirect to /dashboardKeep the PR small. A 60-line PR gets a careful review in ten minutes; a 2,000-line PR gets a rubber-stamp "LGTM" because nobody can hold that much in their head. If a branch is sprawling, split it.
Step 6: request review
Click "Reviewers" in the sidebar and pick the people who should look at it. On a team with branch protection on main, a required-review rule means the PR cannot merge until someone approves, so this step is not optional. How strict that gate is, and who has to sign off, depends on the branching strategy your team follows. If your repo runs CI, GitHub Actions checks run automatically and show up as pass/fail status right on the PR.
Draft pull requests are for work you want visible but not yet reviewable. When you open the PR, click the dropdown next to "Create pull request" and choose "Create draft pull request". A draft cannot be merged and does not ping reviewers, which is exactly what you want for an early CI run or a "here is my direction, sanity-check it" share. When it is ready, click "Ready for review" and it converts to a normal PR. GitLab has the same feature: prefix the MR title with Draft:.
Step 7: address feedback
Reviewers leave comments. You respond by pushing more commits to the same branch. There is no second command to learn here: any commit you push to add-login-page shows up on the open PR automatically.
# make the requested changes, then
git add .
git commit -m "Validate email format per review comment"
git pushNotice the push is now just git push (no -u) because the upstream is already set. The new commit appears in the PR, the reviewer re-reads the diff, and the conversation continues until they approve.
If main has moved on while your PR sat open, you may need to update your branch. Either merge main into your branch or rebase onto it; the trade-offs are in git merge vs git rebase, and fixing divergent branches when main has moved on covers the case where both branches have new commits. If updating surfaces a conflict, resolving merge conflicts walks through it. And if you ever push something you immediately regret, undoing the last commit gets you out before anyone notices.
Step 8: merge
Once the PR is approved and checks pass, the green "Merge pull request" button is live. GitHub gives you three merge strategies:
| Strategy | What it does | When I reach for it |
|---|---|---|
| Create a merge commit | Keeps every commit plus a merge commit | Long-lived feature branches where the history matters |
| Squash and merge | Collapses all branch commits into one | The default for most feature PRs; keeps main linear and readable |
| Rebase and merge | Replays each commit onto main, no merge commit | When each commit is already clean and you want them preserved |
For most day-to-day work I use squash and merge: a messy branch with eight "fix typo" commits becomes one clean commit on main. After the merge, delete the branch (GitHub offers a button), then clean up locally:
git switch main
git pull
git branch -d add-login-pageGitLab's merge request has the same options under different labels ("Merge", "Squash commits"), plus an optional "Delete source branch" checkbox.
Pull request vs merge request: same thing, two names
| GitHub | GitLab | |
|---|---|---|
| Feature name | Pull request (PR) | Merge request (MR) |
| Branch dropdowns | base / compare | target / source |
| Draft mode | "Create draft pull request" | Draft: title prefix |
| Auto-close issue | Closes #142 | Closes #142 |
There is no technical difference in what they do. GitHub picked "pull request" (you are asking the maintainer to pull your branch), GitLab picked "merge request" (you are asking to merge it). Bitbucket also uses "pull request". The branch-push-review-merge loop is identical across all three.
Forking: the open-source variant
Everything above assumes you can push branches directly to the repo, which is true for your own projects and your team's repos. For an open-source project you do not have write access to, you first fork it to your own account, push your branch to the fork, then open the PR from your fork's branch into the original repo's main. The PR form handles the cross-repo part for you. The difference between forking and cloning is its own topic, covered in fork vs clone, and keeping a fork current is in syncing a fork with upstream.
FAQ
If you are still finding your feet with branches, remotes, and the everyday commands underneath all this, the Git for beginners hub ties the whole series together.
Sources
Authoritative references this article was fact-checked against.
- GitHub Docs: Creating a pull requestdocs.github.com
- GitHub Docs: About pull requestsdocs.github.com
- Pro Git: Contributing to a Projectgit-scm.com





