A merge commit is just like another commit, the state of your repository at a given point in time plus the history it evolved from.

The one thing special about a merge commit is that it has at least two predecessors, therefore a plain vanilla diff doesn't make sense, you can only compare the merge with one of the predecessor, which yields the changes from the other parent(s)

To avoid merge commits, you can rebase your changes before pushing them to a remote repository.

Answer from Jens Schauder on Stack Overflow
🌐
Git
git-scm.com › docs › git-merge
Git - git-merge Documentation
Incorporates changes from the named commits (since the time their histories diverged from the current branch) into the current branch. This command is used by git pull to incorporate changes from another repository and can be used by hand to merge changes from one branch into another.
🌐
Brandon Pugh's Blog
brandonpugh.com › posts › tips for creating merge commits
Tips for creating merge commits | Brandon Pugh's Blog
August 31, 2024 - Merge commits that merge a pull request are more straight forward because, these days, they’re generally created by the git hosting service so you know they only contain all the changes from that feature branch.
🌐
Atlassian
atlassian.com › git › tutorials › using branches › git merge
Git Merge | Atlassian Git Tutorial
Git merge will combine multiple sequences of commits into one unified history. In the most frequent use cases, git merge is used to combine two branches. The following examples in this document will focus on this branch merging pattern.
🌐
GitHub
docs.github.com › articles › about-merge-methods-on-github
About merge methods on GitHub - GitHub Docs
Pull requests with squashed commits are merged using the fast-forward option. To squash and merge pull requests, you must have write permissions in the repository, and the repository must allow squash merging. You can use squash and merge to create a more streamlined Git history in your repository.
🌐
GeeksforGeeks
geeksforgeeks.org › git › how-to-merge-commits-in-git
How to Merge Commits in Git? - GeeksforGeeks
July 23, 2025 - This method allows you to merge all changes from a branch but combine them into a single commit. ... git checkout main git merge --squash feature git commit -m "Merged feature branch as a single commit"
🌐
Medium
medium.com › @talgoldfus › better-understanding-gits-work-flow-in-order-to-properly-deal-with-merge-conflicts-part-i-760a366fc997
Better understanding Git’s work flow in order to properly deal with merge conflicts — Part I | by Tal Goldfus | Medium
June 22, 2016 - in both cases git tries to auto-merge changes. If the Master branch has changed since the new branch was created, then merging the new branch into the master branch will create a merge commit. This is a typical merge.
Find elsewhere
🌐
GitLab
docs.gitlab.com › user › project › merge_requests › methods
Merge methods | GitLab Docs
Squash commits when merging should be set to either: ... Either Allow or Encourage, and squashing must be selected on the merge request. The squash merge graph is also equivalent to these commands: git checkout `git merge-base feature main` git merge --squash feature git commit --no-edit SOURCE_SHA=`git rev-parse HEAD` git checkout main git merge --no-ff $SOURCE_SHA
🌐
DEV Community
dev.to › iamafro › how-to-merge-a-specific-commit-into-another-branch--oak
How to merge a specific commit into another branch - DEV Community
February 15, 2018 - First you checkout the branch you want to merge the commits into ... What this does is, "It applies the change introduced by the commit at the tip of the working branch and creates a new commit with this change". The issue I had with that was, I had made a couple of commits and I needed all those commits in the master branch. That's when I found it. What did I find? you may be asking. Gitlens is what I found.
🌐
Ken Muse
kenmuse.com › blog › understanding-how-git-merges-work
Understanding How Git Merges Work - Ken Muse
January 2, 2026 - This is how Git represents the fact that two lines of development have come together. The merge commit preserves the parallel history – you can see that development happened in parallel. But here’s the crucial difference: Git doesn’t record why the merge happened, which branch the changes came from by name, or maintain any ongoing tracking.
🌐
Git
git-scm.com › book › en › v2 › Git-Branching-Basic-Branching-and-Merging
Git - Basic Branching and Merging
The commit message by default looks something like this: Merge branch 'iss53' Conflicts: index.html # # It looks like you may be committing a merge. # If this is not correct, please remove the file # .git/MERGE_HEAD # and try again. # Please enter the commit message for your changes.
🌐
Luke Merrett
lukemerrett.com › different-merge-types-in-git
Different Merge Types in Git
August 7, 2021 - It will also create a merge commit, a special type of “empty” commit that indicates when the merge occurred ... Most descriptive and verbose history, tells us exactly when things happened, helps give the best context about code changes · ...
🌐
CodeSignal
codesignal.com › learn › courses › working-with-branches › lessons › generating-merge-commits
Generating Merge Commits
Instead, Git will create a merge commit to combine the changes from both branches while preserving the history of each.
🌐
HackerNoon
hackernoon.com › using-git-merge-to-merge-changes-from-other-branches
Using Git Merge to Merge Changes from other Branches
October 25, 2022 - Discover Anything · Hackernoon · Signup · Write · Light-Mode · Classic · Newspaper · Minty · Dark-Mode · Neon Noir
🌐
GitHub
docs.github.com › en › repositories › configuring-branches-and-merges-in-your-repository › configuring-pull-request-merges › configuring-commit-merging-for-pull-requests
Configuring commit merging for pull requests - GitHub Docs
If you select more than one merge method, collaborators can choose which type of merge commit to use when they merge a pull request. If there is a protected branch rule in your repository that requires a linear commit history, you must allow squash merging, rebase merging, or both.
🌐
DevTutorial
devtutorial.io › how-to-force-a-merge-commit-git-p1330.html
How to force a merge commit (Git) - Devtutorial
git merge origin/stable-3.2 --no-ff --edit --quiet · Step 3 : The commit message editor will open, and you can write a commit message.
🌐
GeeksforGeeks
geeksforgeeks.org › git › git-merge
Git Merge - GeeksforGeeks
May 9, 2026 - Git Merge combines changes from different branches into a single branch, integrating work while preserving history. It helps unify development without losing progress. Preserves commit history and creates a merge commit when needed.
🌐
Reddit
reddit.com › r/opensource › merge commit, squash, or rebase: how do you close pull requests on github?
r/opensource on Reddit: Merge Commit, Squash, or Rebase: how do you close Pull Requests on GitHub?
December 30, 2022 -

When Merging a Pull Request on GitHub, you mainly have three options: merge commit, squash or rebase.

Is there anything wrong with always doing a merge commit? Well, there isn’t right or wrong here, but considering the other strategies will likely bring you some benefits.

I made a video about it: https://www.youtube.com/watch?v=rFRtsiQEJZw

In the video, I will go into detail about the three strategies, and I will also do a "live demo" with GitHub stickers and JS pins, if you're curious I'd recommend you to watch the video, otherwise you can find the full-text content here below.

Merge Commit

Merge commit is probably the most common as it’s the default option on GitHub and also the default behavior when you manually use git merge.

The history of all your commits remains untouched and on the main branch, you see an additional commit that merges all your branch content.

The biggest advantage is that you can easily track down the exact commit where a line has been modified, as long as there aren’t too many commits.

The downside is that when multiple commits are on multiple branches, the history quickly becomes really tangled, and following the path of a change can be quite a challenge.

Squash merge

The question is, do you really need to keep track of every single commit? Including typos, missing files, formatting… if the answer is no, then you should consider Squash merge.

When squashing a merge, the result is that you get rid of all commits on the branch and only add a single commit on main with all the content.

As a result, the history is much cleaner and while working on a branch you can do all the commits you want since you know that with the squash all your sins will be forgotten. Kind of.

Who doesn’t like squash merge, usually brings up the fact that you’re losing a lot of commit history, but it’s up to you if you think commits on a branch are valuable when reviewing old activity or rather is just noise.

Rebase

A third way is that you don’t really need a commit that indicates a merge took place, and you still want to end up having all commits in a single, straight line.

Merge commit has all tangled lines plus an extra commit, Squash is a straight line but loses the history so here comes Rebase, which keeps the history AND the straight line AND doesn’t require an extra commit for the merge.

Does this make Rebase the best strategy ever? Well... actually not necessarily, because it has some potentially destructive side effects.

If you get a merge conflict during a rebase, it’s fairly easy to unintentionally lose parts of your code code and if you need to catch up on multiple commits you might end up resolving a merge conflict for every single commit, rather than just one in the other merge strategies.

My two cents

After this overview, what do you think? Let me know in the comments!

In my opinion, if branches don’t stay open for a long time, squash merge is a good option, also I’m not a fan of rebase because it’s too easy to make huge mistakes. But before deciding which strategy to apply you should take some considerations.

For example, how often do you and your team have to look back at old commits? How many members are on the team? Does your CI need the full commit history?

Think about it, talk with your team, and you can find together the best strategy for your own use case.

Actually, a good strategy could be subscribing to my YouTube channel if you like my content!

Config

If you want to enforce only some merge strategies on GitHub, head over to the settings of your repository and scroll down a little bit.

Here you will find three sections to allow merge commit, squash, or rebase in your pull requests.

If you keep only one selected, all PRs in your repo will be merged with that specific strategy.

For the first two, you can also define the default commit message that can take information from the PR or the commits in the branch in case of a squash.

As you can see rebase doesn’t have this option and the reason is simple. As we just saw, rebasing does not create an extra commit for the merge, so there is nothing to do here. The existing commits are simply moved to the head of your branch.

Since you’re already on this page, if you scroll down a little bit more you might also want to check this flag to automatically delete branches after a PR is merged.

Closing

If you have any preference or you want to share your experience, please leave a comment, I'll be really happy to hear from you!

With that said, happy new year, may it bring you a lot of merged PRs and no merge conflicts!

Top answer
1 of 3
3
Always commit work as soon as possible, even if you're in the middle of something and don't have working product yet. always make separate branches for separate changes, and keep the change in each branch relatively small. Create a MR as soon as your change works and the pipeline (including testing, linting, etc) works. If you follow the above strategies, i think squash commits really are the best option. You don't clutter your history with loads of small "low information" commits, you dont end up seeing a line of code first entered in a commit only to realize it was 5 commits later when the code actually ran succesfully. Instead, you have a clear commit where the new functionality was added, and that commit contains working code and unit tests. In fact, if your tasks are defined small and clear enough, any time you have a working addition to your codebase, that should probably be exactly the moment your task is done and you want to start a MR(excluding unit tests, documentation and linting). So in theory all the commits you 'cut out' are only commits that don't have a working product in them anyway. Of course, if your assumptions dont work, and you have longer lived branches or big MRs with multiple/bigger features, or with multiple people adding multiple different things to one branch, you'll lose a lot of info with squash commit.
2 of 3
1
Most of the time, I would recommend using merge commit when merging PRs. This should be the default flow that you use with most PRs. Except when the contributors makes a complete mess of the history, such as they clicked on sync with master/main two dozens times for what should've been half dozen commit change, so that there's more merge commits than there is actual content commits, or they were committing two dozens commit for a one line changes, then I would rebase/squash them, because those are unnecessary complexity that I don't have to deal with. If you're contributing to projects, please don't re-sync the PR branch to master unless there's a merge conflict, or you're asked to do that by the maintainer. Each re-sync creates an unnecessary merge commit, which clutters the history. If you just want to re-run the CI, the maintainer will do that themselves when they're looking at the PR if they think it's necessary. I don't really want to rebase your work, because it strips off any GPG signatures you may have on the commit, and it'll likely screw your local branches as well. But if your git history looks like a completely avoidable dog's breakfast, then I'll have to do that.