Merging is the final step of the pull request lifecycle — the moment a proposed change becomes a permanent part of the main codebase. GitHub gives you several ways to merge and a set of controls that determine who can merge and under what conditions. Understanding these choices ensures merges happen cleanly and the resulting history is what you intend it to be.
Prerequisites for Merging
Before a pull request can be merged, it must satisfy any requirements the repository has configured. Common requirements include:
| Requirement | What it means |
|---|---|
| Required reviews | A minimum number of approvals from designated reviewers |
| Passing status checks | All configured CI tests and linting must pass |
| No merge conflicts | The branch must merge cleanly into the base branch |
| Up-to-date branch | The PR branch must include the latest commits from the base branch |
If any of these are not satisfied, the merge button is greyed out or disabled. GitHub displays a clear explanation of what is blocking the merge at the bottom of the Conversation tab.
The Three Merge Strategies
GitHub offers three ways to merge a pull request. The choice is made via the dropdown on the merge button. Each produces a different history.
1. Merge Commit (Create a merge commit)
The default strategy. GitHub performs a standard three-way merge and creates a merge commit with two parents — one from the base branch and one from the PR branch.
Before:
main: A -- B -- C
\
feature: D -- E
After merge commit:
main: A -- B -- C ----------- M
\ /
feature: D ------------ E
The merge commit M permanently records that these two lines of history joined at this point. The full history of the feature branch is preserved.
Use when: you want to preserve the complete history of the branch, including every intermediate commit, and explicitly mark where the merge happened.
2. Squash and Merge
All commits from the PR branch are combined into a single new commit applied directly to the base branch. The branch's individual commits do not appear in the base branch's history.
Before:
main: A -- B -- C
feature: D -- E -- F (3 commits)
After squash and merge:
main: A -- B -- C -- S (S = all changes from D, E, F combined)
The squash commit S contains all the changes but none of the intermediate commit messages. GitHub provides an editor where you can write a clean summary commit message before merging.
Use when: the branch has many "work in progress" or fixup commits that add noise to the history, and you want the base branch history to reflect only meaningful, polished commits.
3. Rebase and Merge
Each commit from the PR branch is replayed individually onto the tip of the base branch — no merge commit is created. The result is a perfectly linear history.
Before:
main: A -- B -- C
feature: D -- E
After rebase and merge:
main: A -- B -- C -- D' -- E'
D' and E' are new commits — they contain the same changes as D and E but have been reapplied on top of C. The original commits on the PR branch are abandoned.
Use when: you want a clean linear history without merge commits, and the individual commits on the branch are well-written and meaningful enough to stand on their own in the base branch history.
Comparison
| Strategy | Creates merge commit | Preserves branch commits | Linear history |
|---|---|---|---|
| Merge commit | Yes | Yes | No |
| Squash and merge | No | No (combined into one) | Yes |
| Rebase and merge | No | Yes (replayed) | Yes |
Repositories can restrict which strategies are available. Go to Settings → General → Pull Requests to enable or disable each option.
Merging on GitHub
Once all requirements are satisfied, the merge button at the bottom of the Conversation tab becomes active:
- Click the dropdown arrow next to the merge button and select your preferred strategy.
- Click the merge button.
- GitHub creates the merge commit (or squash/rebase commit), updates the base branch, and marks the PR as merged.
- Any linked issues using
Closes #norFixes #nkeywords are automatically closed. - GitHub offers to delete the PR branch — click Delete branch to clean up.
The PR page is now marked as Merged (purple label) and is permanently archived with its full discussion history intact.
Merging Locally
Instead of using GitHub's merge button, you can merge the PR locally and push — GitHub will detect the merge and automatically close the PR:
# Fetch the PR branch
git fetch origin feature/dark-mode
# Switch to main
git switch main
# Merge the branch
git merge --no-ff origin/feature/dark-mode
# Push the updated main
git push origin main
The --no-ff flag forces a merge commit even when a fast-forward is possible, preserving the branch topology in the history.
GitHub automatically closes the PR when it detects that the branch's commits have been integrated into the base branch, regardless of whether the merge happened on GitHub or locally.
Closing a Pull Request Without Merging
Sometimes a PR should be closed without merging — the approach was wrong, the issue was solved another way, or the work is no longer needed. To close without merging:
- Scroll to the bottom of the Conversation tab.
- Click Close pull request.
The PR is marked as Closed (red label). No changes are merged. The branch and all discussion are preserved — a closed PR can be reopened at any time if needed.
To close a PR and simultaneously delete the branch:
- Close the PR.
- Click Delete branch in the confirmation banner that appears.
After the Merge — Syncing Up
After a PR is merged, everyone working on related branches should sync with the updated base branch to avoid falling behind:
# Update your local main
git switch main
git pull origin main
# Delete the merged branch locally
git branch -d feature/dark-mode
# If working from a fork, also sync the fork
git fetch upstream
git merge upstream/main
git push origin main
What the Merged PR Record Preserves
A merged pull request is a permanent record in GitHub's history. Even after the branch is deleted, the PR page remains accessible and shows:
- The complete conversation — every comment, review, and suggestion.
- Every commit that was part of the branch.
- The status check results.
- Who reviewed and approved.
- The exact diff that was merged.
This is one of GitHub's most valuable properties for teams: you can look at any change to main and trace it back to the PR where the decision was made, see who approved it and why, and read the full discussion that shaped it.
Configuring Merge Options for a Repository
Repository administrators can control which merge strategies are available and set merge hygiene rules:
- Go to Settings → General → Pull Requests.
| Option | What it controls |
|---|---|
| Allow merge commits | Enables the standard merge commit strategy |
| Allow squash merging | Enables squash and merge |
| Allow rebase merging | Enables rebase and merge |
| Automatically delete head branches | Deletes the PR branch automatically after merging |
| Require linear history | Only allows squash or rebase merges — no merge commits |
Enabling Automatically delete head branches removes the need to manually click Delete branch after every merge — a small quality-of-life improvement that keeps the branch list clean automatically.
Summary
| Action | How to do it |
|---|---|
| Merge with a merge commit | Merge button → Create a merge commit |
| Squash and merge | Merge button dropdown → Squash and merge |
| Rebase and merge | Merge button dropdown → Rebase and merge |
| Merge locally | git merge, then git push origin main |
| Close without merging | Close pull request button |
| Delete the branch after merging | Delete branch button (or enable auto-delete in settings) |
| Sync after merge | git switch main && git pull origin main |