DEV Community

Wen Ping
Wen Ping

Posted on Edited on Originally published at anguskit.com

How to merge a pull request: choose a merge commit, squash, or rebase

This article explains how Create a merge commit, Squash and merge, and Rebase and merge differ when you merge a pull request. After reading it, you can open Settings → Pull Requests, leave on only the method your team agreed to use, see what kind of commit will appear on main, and delete the local branch that was already merged, using the command that matches the method.

A pull request is a request to merge one branch into another. AngusGit calls it a pull request.

The examples use xlliu/test-pr-example. The clone URL is https://git.anguskit.com/xlliu/test-pr-example.git. To try all three methods, this repository has Allow merge commits, Allow squash merging, and Allow rebase merging all on. Automatically delete head branches is off. A new repository defaults to the first two on, rebase merging off, and automatic branch deletion off. Among the records already merged, #2 left the merge commit Merge pull request #2 from feature/close-reopen on main. When this article draws what the history looks like, it still uses a source branch with three commits: commits 1, 2, and 3 merging into a main that already has A and B.

History on main after the three merge methods: a merge commit, one squashed commit, or a straight line from rebase

1. What main looks like after each method

Method What is added on main Author and when to use it
Create a merge commit The three commits from the branch enter main as they are, plus a merge commit (a fast-forward moves main forward and skips the merge commit) The original commits keep their authors. The system creates the merge commit. Use this when you want the full branch history
Squash and merge One new commit, whose content is the combined change of the three commits The author is the pull request author. The committer is the person who clicked merge. Use this when you want the small commits pressed into one
Rebase and merge The three commits are replayed one by one on top of the latest commit on main, with new commit hashes Each commit keeps its original author and message. Use this when every commit is tidy and you want a straight-line history

One more case: if you choose Create a merge commit, and main received no new commits between the moment the branch was created and the merge, AngusGit moves main to the last commit on the branch and does not create a merge commit. The result is a straight line, the same shape as a rebase merge. That move is called a fast-forward.

2. Choose which methods the repository allows

  1. Open settings Open the repository, go to Settings, and choose Pull Requests on the left. You need permission to manage the repository.
  2. Choose the allowed methods The three switches are Allow merge commits ("Add all commits from the head branch to the base branch"), Allow squash merging ("Combine all commits into a single commit"), and Allow rebase merging ("Rebase all commits onto the base branch"). A new repository turns on the first two and leaves rebase merging off. If the team agreed to use only one method, turn on only that one, so nobody picks the wrong method at merge time.
  3. Decide whether to delete the branch after merge On the same page, Automatically delete head branches ("Delete branches after pull requests are merged") is off by default. When it is on, AngusGit deletes the source branch after the pull request merges.
  4. Save Click Save Changes. The message is Pull Requests settings saved.

Pull request settings on xlliu/test-pr-example: all three merge methods on, automatic branch deletion off

Leave at least one method on. If you turn all three off, the settings still save, and after that no pull request can be merged.

3. Choose the method when you merge

When the pull request meets the merge conditions, open the Conversation page and click Merge pull request. The confirm dialog says "Choose merge method and confirm the merge".

  1. Pick a method All three options are listed: Create a merge commit ("All commits will be added to the base branch"), Squash and merge ("Combine all commits into a single commit"), and Rebase and merge ("Rebase commits onto the base branch"). A method that is off in repository settings is gray and cannot be clicked. When the dialog opens, the default is the first allowed method in that order.
  2. Check the commit message Commit message is filled in from the method. You can edit it:
    • Create a merge commit: the first line is Merge pull request #<number> from <source branch>. After #2 on xlliu/test-pr-example was merged, the commit message on main is Merge pull request #2 from feature/close-reopen.
    • Squash and merge: the first line is the pull request title, and the pull request description follows. That text becomes the message of the one new commit on main, so it is worth editing until it says what this change does.
    • Rebase and merge: the box is gray and says "Rebase and merge does not create a merge commit message", because each commit keeps its original message.
  3. Confirm Click Confirm merge. After Pull request merged successfully, the page returns to the pull request list, and this item's status is Merged.

The confirm dialog appears only after Merge pull request can be clicked. The open request xlliu/test-cicd-example #1 already has both pipelines successful, and the button is still gray. The card says "Reviews are still pending and must be approved before merge". After the button can be opened, the text under the dialog title is "Choose merge method and confirm the merge". The three options are Create a merge commit, Squash and merge, and Rebase and merge. The one that is off in repository settings is gray.

The merge button on pull request #1 is gray: checks passed, and the review is not finished

4. Clean up locally after the merge

Update local main first:

git switch main
git pull
Enter fullscreen mode Exit fullscreen mode

Then delete the local branch that was merged. The three methods behave differently at this step:

Merge method Delete command Why
Create a merge commit git branch -d feature/close-reopen The commits from the branch are already on main as they were, so a safe delete works. #2 was merged this way
Squash and merge git branch -D feature/close-reopen main has a new commit. After you confirm the merge, force-delete with -D
Rebase and merge git branch -D feature/close-reopen main has new commit hashes. After you confirm the merge, force-delete with -D

The remote source branch is kept by default. When Automatically delete head branches is off, open the repository Branches tab, click Delete branch on that row, and confirm. The message is Branch deleted successfully.

A rebase merge also rewrites the source branch on the server: after the merge, the source branch points at the three new commits. If you want to keep working on that branch after the merge, run git fetch and git reset --hard origin/feature/close-reopen locally so you match the server, then commit again. reset --hard drops local changes that were not pushed. Confirm that before you run it. A simpler approach is to start a new branch from the latest main.

5. When the merge fails

What you see Why What to do
The method you want is gray in the confirm dialog That method is off under repository Settings → Pull Requests Ask a repository administrator to turn on the switch, or use a method that is already allowed
Repository does not allow rebase merge method An administrator turned this method off after you opened the confirm dialog Refresh the page and pick an allowed method
Merge conflicts detected, please resolve the conflicts before merging The branch and main changed the same code. A rebase merge hits this more easily, because it applies commits one by one: the combined change can be clean while one commit in the middle still conflicts Merge main into the branch locally, resolve the conflict, push, and merge again. Or use squash and merge
You chose create a merge commit, and main has no merge commit main had no new commits after the branch was created, so AngusGit fast-forwarded This is a normal result. The code is already merged
After the merge, git branch -d cannot delete the local branch You used squash and merge or rebase and merge, so the commit ids on main differ from the local branch After you confirm the merge, use git branch -D

Frequently asked questions

Can you undo a merge?

The page has no button that undoes a merge. To take it back, create a reverse commit locally with git revert, push it to a new branch, and open a pull request into main. For a merge that used Create a merge commit, git revert -m 1 <merge commit id> takes back the whole branch in one step. For a merge that used Squash and merge, revert that one commit.

Should the team use one method for every pull request?

Yes. If you mix them, some requests on main are one commit and others are a string of commits. Looking back through history, and reverting, both start with figuring out which method was used. The simplest setup is to turn on only the agreed method under Settings → Pull Requests.

After a squash merge, can you still see the original commits?

Yes. Open the merged pull request. The Commits tab still lists the three commits from before the merge. The history of main contains only the one squashed commit.

Why is rebase merging off by default?

A rebase merge rewrites the source branch on the server, and every commit on the branch must apply onto main on its own without a conflict. Turn it on when the team wants a straight-line history and every commit is written cleanly.

Summary

The three merge methods put the same code in. The difference is the history on main: Create a merge commit keeps every commit plus a merge commit, Squash and merge presses them into one new commit, and Rebase and merge replays each commit into a straight line. A repository administrator decides which methods are allowed under Settings → Pull Requests. A team should agree on one. Check Commit message when you merge, and write it clearly for a squash merge. After the merge, update local main. Delete a local branch that was squash-merged or rebase-merged with git branch -D.

Conclusion: Under repository Settings → Pull Requests, turn on only the merge method the team agreed to use. Choose Squash and merge when one request should become one commit, Create a merge commit when you want the full branch record, or Rebase and merge when you want a straight line that keeps the original commits. After a squash or rebase merge, clean up the local branch with git branch -D.

Related articles

Top comments (0)