The green merge button doesn’t look the same on every repository. Some show one option, some show several, and a few show none at all because settings or branch rules took it away.
What the button does differs too. A merge commit, a squash and a rebase each write different history into the base branch, and the repository settings decide which of them you’re allowed to use.
The usual case is a feature branch going into main or develop once review is done and status checks pass. You can do it on the website or with the GitHub CLI. A plain local git merge works as well.
One detail trips up people who come from plain Git. When GitHub does a rebase and merge, it always updates the committer information and creates new commit SHAs, so the commits that land on the base branch are copies of your originals (GitHub Docs, as of October 2026).
What do you need before merging a branch on GitHub?
The merge button goes gray or disappears when anything below is missing.
- Squash and rebase merges both need write permissions, and the repository has to allow the method you want (GitHub Docs).
- The pull request has a compare branch holding your changes and a base branch that receives them.
- Where the base branch demands approving reviews and passing status checks, those have to be in place.
- A draft pull request can’t be merged until someone marks it ready for review.
A branch comparison before the merge catches problems early. The compare page lists changed files and flags branches that cannot merge automatically.
Pull requests display a three-dot diff, which measures the topic branch against the merge base, so the diff shows only what the pull request introduces (GitHub Docs). Merging the base branch into the topic branch makes the two-dot and three-dot views identical.
No pull request yet? Create the pull request first, from the compare page or the banner GitHub shows after a push.
How to merge a pull request on GitHub

The merge happens in the merge box at the bottom of the pull request page.
- Open the repository, click the Pull requests tab, and select the pull request you want to merge.
- Scroll to the merge box on the Conversation tab and read the status of reviews and checks.
- Click Merge pull request to add all commits to the base branch. Or open the dropdown arrow and choose Squash and merge or Rebase and merge.
- Edit the commit title and message if the method offers them. Rebase merges keep each original commit message.
- Click Confirm merge, Confirm squash and merge, or Confirm rebase and merge, depending on the method you chose.
When the repository requires reviews, the button stays locked until the approvals exist. A reviewer can approve the pull request from the Files changed tab.
Merge conflicts lock the button too. They get resolved first, and the merge goes through after that.
That plain Merge pull request button is only the default. Often another method fits the situation better.
Merge commit, squash and merge, or rebase and merge: which should you pick?
For most feature branches I’d squash. Teams that need an audit trail tend to stay with merge commits, and rebase and merge makes sense once everyone on the team curates their commits carefully.
| Method | History result | Best for | Main drawback |
|---|---|---|---|
| Merge commit | All commits plus one merge commit | Audit trail, long-running branches | Busier commit graph |
| Squash and merge | One commit per pull request | Small features, messy work-in-progress commits | Individual commits lost |
| Rebase and merge | Commits replayed one by one, no merge commit | Linear history, curated commits | New SHAs and committer info |
Pull requests merge with the –no-ff option, except squashed or rebased pull requests, which use fast-forward merging (GitHub Docs). So only the merge commit method adds a merge commit to the graph.
Merge commit
Merge pull request adds every commit from the feature branch to the base branch inside a merge commit.
The original commits and their SHAs stay intact, and the history shows exactly when a branch landed. That makes it the safe pick for long-running branches that several developers share.
The downside is clutter. History fills with merge commits, so reading it cleanly takes git log –first-parent, and the method is blocked outright when the branch requires linear history.
Squash and merge
A pull request with 14 commits titled “wip”, “fix”, and “fix again” lands as one clean commit. That is the whole appeal.
Under the hood this is commit squashing, applied at merge time. The default message is the commit title and message when the pull request has one commit, or the pull request title plus a list of commits when it has two or more (GitHub Docs).
Repository settings can change that default to the pull request title alone, the title plus commit details, or the title plus description. The pull request author is normally credited as author of the squashed commit, and the other commit authors are added as co-authors.
There’s a catch with the head branch. If you keep working on it after squashing and open a new pull request between the same branches, the previously squashed commits show up in it again (GitHub Docs). Delete the branch and start a fresh one instead.
The other drawback is that the individual commits are gone from the base branch, which makes bisecting a bad change coarser.
Rebase and merge
Linear history, no merge commit, every original commit kept.
A merge commit keeps the history of both branches. Rebasing replays the commits on top of the base branch instead, which is why no merge commit appears.
GitHub’s version differs slightly from rebasing with git on the command line. It always updates committer information and creates new commit SHAs, while a local git rebase on top of an ancestor commit leaves the committer untouched (GitHub Docs).
What you get is a straight line of commits that reads like a changelog. What you pay is new SHAs, so the commits on your local branch no longer match the merged ones. The button is also unavailable when the pull request has merge conflicts, when rebasing runs into conflicts, or when GitHub considers the rebase unsafe because it would produce a different result than a merge.
The documented workaround is to rebase the topic branch onto the base branch locally, resolve any conflicts on the command line, and force-push the rebased commits to the pull request’s head branch. Anyone with write permissions can then use the Rebase and merge button (GitHub Docs).
Squash fits small, well-titled pull requests. Rebase only pays off when each commit already tells a clean story, and if the team wants to see when a branch landed, a merge commit does that without any extra work.
Repository settings control which buttons appear. Select more than one method under Settings, General, Pull Requests, and contributors choose per merge (GitHub Docs).
How to merge a branch from the GitHub CLI, the command line or GitHub Desktop
From a terminal, gh pr merge handles a pull request directly. A local merge is git merge followed by a push, and GitHub Desktop does it from the Current Branch menu.
GitHub CLI
The gh pr merge command takes a pull request number, URL, or head branch. With no argument it picks the pull request tied to the current branch.
Once you know your way around the GitHub CLI, a squash merge that also deletes the branch is one line (GitHub Docs).
gh pr merge 523 --squash --body "my squash commit" --delete-branch- Pick the method with –merge, –squash or –rebase (short forms -m, -s, -r).
- –delete-branch removes the local and remote branch after the merge.
- –auto holds the merge until the requirements are met.
- –admin merges a pull request that does not meet requirements, using administrator privileges.
When the target branch requires a merge queue, no method flag is needed. The command turns on auto-merge if checks are pending, or adds the pull request to the queue if they passed, and –admin bypasses the queue (GitHub CLI manual).
Local git merge
- Switch to the base branch with
git switch main. - Pull the latest changes with
git pull origin main. - Merge the feature branch using
git merge feature-branch. - Push the result with
git push origin main.
The two-branch merge in Git fast-forwards when main has not moved and creates a merge commit when it has. Add –no-ff to force the merge commit either way.
A base branch that requires pull requests rejects the push in step 4. Open a pull request instead, and run gh pr checkout when conflicts need local work or you want to test the changes first.
GitHub Desktop
GitHub Desktop merges into whichever branch is checked out, so switch to the base branch first.
- Click Current Branch and select the base branch.
- Click Choose a branch to merge into BRANCH.
- Select the feature branch, then click Merge BRANCH into BRANCH.
Conflicts appear as a warning above the merge button. The Branch menu also offers Squash and Merge into Current Branch, plus a rebase option (GitHub Docs).
The merge stays local until you push it.
How to resolve merge conflicts before merging
Git stops and asks for help when two branches change the same lines of a file, because it can’t pick a winner. Until someone resolves it, the pull request cannot merge.
Each clash gets marked with conflict markers inside the file.
<<<<<<< feature-branch
timeout = 30
=======
timeout = 60
>>>>>>> mainYour branch sits above the line of equals signs, and the base branch sits below it.
You can keep one side or combine both. Sometimes neither is right and you write something new. Delete all three marker lines either way.
Resolving in the web editor
The web editor only handles simple conflicts caused by competing line changes. Every other conflict type has to be resolved locally (GitHub Docs).
- Click the pull request, then Resolve conflicts.
- Delete the markers and keep the content you want.
- Click Mark as resolved for each file, then click Commit merge after the last conflict is gone.
One warning from the docs: resolving on GitHub merges the entire base branch into the head branch, so check that you want that commit on the head branch.
A grayed-out Resolve conflicts button means the conflict is too complex for the editor. Switch to the command line or another Git client, or read this walkthrough on resolving conflicts in GitHub for the browser route.
Resolving locally
- Check out the feature branch with
git switch feature-branch. - Bring the base branch in with
git fetch origin, thengit merge origin/main. - Run
git statusto list the conflicted files, open each one, and resolve the markers. - Run
git addon each resolved file, thengit commit. - Push with
git pushso the pull request picks up the resolution.
Visual Studio Code highlights the markers and offers Accept Current Change, Accept Incoming Change, and Accept Both Changes above each block. The finer points of resolving merge conflicts in Git (rerere, mergetool, binary files) go well beyond the pull request flow.
Why is the merge button blocked?
Something is usually unmet when the button is blocked. Reviews may be missing, a required check may be failing or may never have reported, the branch may be behind its base, or the allowed methods in the repository settings may disagree with a ruleset.
| Symptom | Likely cause | Fix |
|---|---|---|
| Merge locked, reviews pending | Required approving reviews missing | Get approval from reviewers with write permission |
| Review requested from specific people | Code owner review required | Wait for owners of the changed files to approve |
| Check pending or failing | Check failed, never reported, or came from the wrong source | Fix or rerun it, then confirm the check name and source |
| Update branch prompt | Branch behind base, up-to-date rule on | Merge the base branch into the head branch |
| Chosen method missing or rejected | Repository setting and ruleset disagree | Align both on the same allowed methods |
| Squash and merge refused | Signed commits required and the head branch has unsigned commits | Rewrite and sign the commits on the head branch, or ask someone with bypass permission to merge; a local squash merge must be signed before pushing |
Reviews and code owners
When required reviews are on, collaborators can only push to a protected branch through a pull request approved by the required number of reviewers with write permissions (GitHub Docs).
Code owners are requested automatically when a pull request touches files they own, except on draft pull requests. Marking the draft ready for review notifies them. The CODEOWNERS file becomes a hard gate only when the branch protection rule turns on Require review from Code Owners.
Status checks
To count as required, a status check must have completed successfully in that repository within the past seven days (GitHub Docs). A check that last ran eight days ago cannot be selected, which surprises teams with quiet repositories.
Skipped checks need care, though GitHub’s pages do not contradict each other. The protected branches page accepts a skipped status as passing, and a job skipped by a conditional reports success. A workflow skipped by path filtering, branch filtering or a commit message is different: its checks stay Pending, and a pull request that requires them cannot merge (GitHub Docs).
Checks come from your continuous integration setup, so a renamed job or a check from an unexpected GitHub App stays pending forever.
Method clashes and admin bypass
Merge methods allowed at the repository level can contradict a ruleset’s merge method rule. If the repository forbids rebase merging and the rule allows only rebase, no merge is possible (GitHub Docs).
Repository administrators can merge past unmet requirements unless the protection is set to Include administrators.
How do auto-merge and merge queue work?
Auto-merge merges a pull request as soon as its required reviews and status checks pass. A merge queue does more, since it automates merges into a busy branch and stops incompatible changes from breaking it (GitHub Docs).
Auto-merge
- Auto-merge must be turned on for the repository first.
- The Enable auto-merge button appears only on pull requests that cannot merge yet.
- Anyone with write permission can turn it on.
- Authors and writers can disable it from the merge box.
Without a branch protection rule requiring reviews or checks, a pull request can merge immediately, so the option never shows. That catches people on unprotected repositories.
Merge queue
Anyone with write access can add a pull request to the queue, once it passes its required branch protection checks. The checks run on GitHub Actions or your own CI provider, and the workflow has to listen to the merge\_group event. Otherwise the required check never reports and the merge fails. A failing status on a pull request’s queue branch drops it from the queue automatically.
Two constraints from GitHub’s documentation (the second appears in the rulesets reference for GitHub Enterprise Cloud and Enterprise Server).
- Branch protection rules with wildcard characters in the branch name pattern cannot use a merge queue.
- The Require merge queue rule is unavailable in organization-level rulesets.
A merge queue delivers the same benefit as requiring branches to be up to date, minus the chore of updating the branch and waiting for checks again (GitHub Docs).
On a low-traffic repository, auto-merge is enough. A busy default branch with several pull requests landing per hour is where the queue earns its setup.
What to do after the merge is done
Once the pull request is merged, the head branch is mostly dead weight and your local main is out of date until you pull. It also helps to know where the Revert button is before you need it.
Delete the branch
Repository admins can turn on Automatically delete head branches under Settings, General, Pull Requests. Branch protection rules and repository rules can still prevent the deletion (GitHub Docs).
Without that setting, deleting the branch is one click from the merged pull request.
Sync your local main
git switch main
git pull origin main
git fetch --prune
git branch -d feature-branchAfter a squash or rebase merge, git branch -d can refuse because Git does not see those commits as merged. Confirm the pull request shows as merged, then use git branch -D.
Revert a merged pull request
Click Revert near the bottom of the merged pull request. GitHub opens a new pull request that reverts the original merge commit, and you merge that one like any other (GitHub Docs).
Writing permission is required, and a missing Revert button means you lack it.
The button is not always enough. If reverting the pull request causes conflicts, or the original was not merged on GitHub (a command-line fast-forward, for example), git revert on the individual commits is the fallback.
Merging Branches in GitHub FAQ
Can you merge a draft pull request?
No. A draft pull request has no working merge button until the author marks it ready for review (GitHub Docs).
Convert it first, then let the required reviews and checks run.
How do you merge upstream changes into a fork?
Add the original repository as a remote named upstream, fetch it, and merge its default branch into yours. The sequence is git remote add upstream URL, git fetch upstream, git merge upstream/main, then git push origin main.
A fork never updates itself, so the sync stays manual.
How do you abort a merge in progress?
Run git merge –abort while conflicts are still unresolved. Git restores the branch to the state it had before the merge started.
After the merge commit exists, the merge is finished. Undo it with a revert instead.
How do you merge a feature branch into develop?
Open the pull request against develop rather than main. GitHub lets you change the base branch while creating the pull request (GitHub Docs).
In Gitflow, feature branches merge into develop, and release branches merge into main.
Setting One Merge Policy for the Whole Repository
Standardize on one merge method per protected branch and enforce it with a branch protection rule or ruleset. Every later pull request then lands in the same shape, whoever clicks the button.
The order of setup matters. GitHub blocks Require linear history until squash merging or rebase merging is allowed in the repository (GitHub Docs).
- Allow only the methods the team will use, then require linear history if squash or rebase is the standard.
- After that, add required reviews and status checks, and finally auto-merge or a merge queue.
The price is flexibility, since contributors lose the option to pick a method per pull request.
Settings names and merge queue availability differ between github.com and GitHub Enterprise Server versions, so recheck them before rollout (verified against GitHub Docs, October 2026). Teams that also want branch naming and release rules written down can pair the policy with a defined Git workflow.
- MongoDB Cheat Sheet - October 20, 2026
- Adding AI Video Generation to a Software Product: Architecture, Cost Guardrails and QA - October 20, 2026
- Show Hidden Characters, Spaces, and Line Endings in Notepad++ - October 19, 2026




