How to squash commits in a GitLab merge request (and when not to)

By Melih Toksari, developer of MergeBell · Updated · 3 min read

Short answer

Select Squash commits in the merge request widget, then Merge: GitLab combines the branch's commits into one commit on the target branch, authored by the merge request's author, plus a merge commit unless the project uses fast-forward merges. A Maintainer or Owner chooses the project's behaviour in Settings › Merge requests › Squash commits when merging: Do not allow, Allow, Encourage or Require. The squash message defaults to the merge request's title. Don't squash long-running branches that keep receiving commits.

Squash and merge turns a merge request’s string of “fix typo” and “address review” commits into one commit on the target branch, so the history shows one change per merge request and reverting it takes one step. Here is how squashing works in GitLab in 2026, where the setting lives, and when not to use it.

Squash when you merge

  1. Open the merge request.
  2. In the merge request widget, make sure Squash commits is selected.
  3. Optionally select Edit commit message to change the squash commit message, or the merge commit message too, depending on the project.
  4. When the merge request is ready, select Merge.

To set it ahead of time, select Edit on the merge request and select Squash commits when merge request is accepted. Anyone who can create or edit the merge request can set this, if the project allows or encourages squashing.

What ends up on the target branch

Each merge adds up to two commits:

  • The squash commit, holding all the branch’s changes. Its author is the user who created the merge request, and its committer is the user who initiated the squash.
  • A merge commit, unless the project uses fast-forward merges. With fast-forward merges you still get the single squash commit, with no merge commit on top.

The squash message comes from the project’s squash commit template, which by default is just %{title}, the merge request’s title.

The project setting: four choices

A Maintainer or Owner sets it in Settings › Merge requests, under Squash commits when merging:

Setting What happens
Do not allow Never squashes, and the option isn’t shown
Allow Squashing is available but cleared by default
Encourage Selected by default, and can be cleared
Require Always squashes, and users can’t change it

If the Squash commits checkbox is missing, squashing is set to Do not allow, either in the project or, on Premium and Ultimate, in a branch rule for the target branch. With Require, the checkbox shows selected and can’t be cleared.

Change the squash commit message

In the same settings page, Squash commit message template replaces the default %{title}. Templates can use variables such as %{title}, %{description}, %{reference}, %{issues}, %{merge_request_author}, %{approved_by}, %{co_authored_by}, %{all_commits} and %{commits_count} (GitLab 19.5 and later). For example:

%{title} (%{reference})

%{co_authored_by}

Changing the template takes the Maintainer or Owner role. Anyone merging can still change the message with Edit commit message.

Squash from the command line or the API

  • GitLab CLI: glab mr merge --squash.
  • Git push options: git push -o merge_request.create -o merge_request.squash opens the merge request set to squash on merge.
  • API: PUT /projects/:id/merge_requests/:merge_request_iid/merge with squash=true, and optionally squash_commit_message.
  • Locally: to tidy your own branch first, run git rebase -i origin/main, mark every commit after the first as squash or fixup, then push, with --force-with-lease if the branch is already on GitLab.

When not to squash

GitLab’s docs advise against squashing long-running branches that keep receiving commits. The squash creates a new commit with a different SHA on the target branch, so the source branch’s history diverges. Its next merge request shows commits that were already merged and a warning that the branch is behind, although the diff still shows only the new changes. If you do squash such a branch, rebase it onto the target, or merge the target back in, after every merge. Otherwise, use merge commits or fast-forward merges, which keep the original commits.

Squash from your phone

MergeBell’s merge sheet has squash and delete branch next to Merge on the free tier, and it lists anything still blocking the merge, so you can see whether it will go through. If the merge request is waiting on a pipeline or an approval, set it to auto-merge with squash selected, and it squashes when it merges.

Frequently asked questions

How do I squash commits when merging in GitLab?

In the merge request widget, make sure Squash commits is selected, optionally select Edit commit message to change the squash commit message, then select Merge. GitLab joins all the branch's commits into a single commit on the target branch.

Why is there no Squash commits checkbox on my merge request?

Squashing is set to Do not allow, either in Settings › Merge requests › Squash commits when merging or, on Premium and Ultimate, in a branch rule for the target branch. Require shows the checkbox selected and locked. A Maintainer or Owner can switch the setting to Allow or Encourage.

What message does a GitLab squash commit get?

By default the merge request's title, from the default squash commit template %{title}. A Maintainer or Owner can change the template in Settings › Merge requests, with variables such as %{description}, %{reference}, %{co_authored_by} and %{all_commits}, and you can edit the message when you merge.

Who is the author of a squash commit in GitLab?

The user who created the merge request. The committer is the user who initiated the squash, usually whoever merged it.

Can I squash commits from the command line?

Yes. glab mr merge --squash squashes when it merges, git push -o merge_request.squash sets it as you push, and the merge API takes squash=true with an optional squash_commit_message. To squash locally, run git rebase -i against the target branch, then push, with --force-with-lease if the branch is already on GitLab.

Sources

Checked against these pages on 21 October 2026. GitLab changes quickly — if something here no longer matches, tell us and we will fix it.

Do this from your phone with MergeBell

Free for the whole review loop: the To-Do inbox, diffs and line comments, approve and merge, pipelines with retry, and push alerts for your To-Dos. Works with gitlab.com and self-managed GitLab 16.0+.

Get MergeBell for AndroidiPhone: email me at launch

On Google Play for Android 12 or later. The iPhone app is coming soon to the App Store. An independent app, not affiliated with GitLab Inc.