GitLab の自動マージが断られた・すぐマージされた・取り消された理由
自動マージは、マージの条件がそろったらマージするよう GitLab に頼むものです。マージの API では GitLab 17.11 から auto_merge: true、それより前は merge_when_pipeline_succeeds: true で、こちらは 17.11 で非推奨になりました。GitLab 17.7 からは、パイプラインだけでなくマージの条件をすべて待ちます(GitLab の自動マージの説明)。それでも GitLab は 405 と答えたり、その場でマージしたり、後で取り消したりします。以下はすべて GitLab のソース(lib/api/merge_requests.rb・app/services/auto_merge/merge_when_checks_pass_service.rb・app/models/merge_request.rb)とマージの API の説明を 2026年10月24日に読んで確かめたものです。
GitLab が auto_merge をどう扱うか
- まず、ふつうのマージと同じ確認:グループがコミットの SHA を求めているのに無ければ
400、あなたのアカウントが行き先のブランチにマージできなければ401、元のブランチが動いていれば409です。GitLab がマージを断った理由へ。 - 待つもの:パイプライン、承認、変更の依頼、未解決のスレッド、下書き、競合、このマージリクエストを止めているほかのマージリクエスト、外部のステータスチェック、セキュリティのポリシー、ロックされたファイルとパス、求められた Jira の課題、タイトルの形、Merge after の日時。
- 待たないもの:閉じたマージリクエスト、コミットの無い元のブランチ、マージの方法が求めるリベース(
need_rebase)。 - 待つものが残っていなければ待ちません。今マージでき、パイプラインが進行中でないときです。Pipelines must succeed が有効なら、パイプラインは終わるまで進行中です。無効なら、待っているか動いている間だけなので、手動のジョブで止まっているパイプラインは待ちません。
- 待たないとき、GitLab はパイプラインが許せばその場でマージします。パイプラインが無く作られてもいないか、最新のパイプラインが成功しているときです。答えはマージ済みのマージリクエストで、
"state":"merged"です。マージできないとわかれば422 Branch cannot be mergedです。 - それ以外は
{"message":"405 Method Not Allowed"}です。止められたふつうのマージと同じ答えで、理由は付きません。
自動マージが設定されると、答えは 200 で、"state":"opened" と "merge_when_pipeline_succeeds":true が付きます。マージトレインを使うプロジェクトでは、GitLab 19.1 から、マージせずにトレインに加えます。
意外な 405 が2つ
- リベースが要る。マージの方法が fast-forward か semi-linear で、automatic rebase before merge が無効なら、行き先のブランチより遅れたマージリクエストにはリベースが要ります。自動マージはこれを待たないので、パイプラインが動いている間でも、レビューが足りなくても、GitLab は 405 と答えます。
- パイプラインが失敗していて、プロジェクトがパイプラインの成功を求めていない。ほかに止めるものが無ければ、GitLab は待たず(待つものが無い)、その場でマージもしません(パイプラインが成功していない)。それで 405 です。
auto_mergeを付けないふつうのマージは通ります。Pipelines must succeed が有効なら、失敗したパイプラインでも自動マージを設定して待ち、再実行したジョブが成功すればマージします。
GitLab が自動マージを取り消すとき
GitLab の説明では、元のブランチに新しいコミットが push されると、それがレビューされるように自動マージを取り消します。マージの方法が fast-forward か semi-linear で automatic rebase before merge が無効なときは、行き先のブランチにコミットが入っても取り消します。そのリベースが有効なら設定を残す動きは GitLab 19.3 で入りましたが、既定では無効の機能フラグの裏です。GitLab が自動マージを取り消したり打ち切ったりすると、マージリクエストのアクティビティに記録が残ります。
取り消すとき
POST /projects/:id/merge_requests/:merge_request_iid/cancel_auto_merge(GitLab 19.5 から):201でマージリクエストが返ります。取り消せない人には403 Forbidden、自動マージが設定されていなければ409Can't cancel the automatic merge(和訳:自動マージを取り消せません)です。POST …/cancel_merge_when_pipeline_succeeds(古い版にある方で、19.5 で非推奨):取り消せない人には401です。設定されていないときも201 Createdで、本文が{"message":"Can't cancel the automatic merge","status":"error","http_status":406}になります。406 は本文の中だけなので、statusを見てください。- 取り消せるのは、作った人と、そのマージリクエストをマージできる人です。
直し方
- リベースが要る 405:リベースして、新しいパイプラインが動いている間にもう一度自動マージにする。
- パイプラインが失敗した後の 405:自動マージにせずにマージするか、失敗したジョブを再実行して、それが動いている間に自動マージにする。
- すぐマージされた:待つものが残っていませんでした。GitLab が待つのは、必須の承認や解決済みのスレッドなど、プロジェクトが有効にした条件だけです。
- 取り消された:新しいコミットを見てから、もう一度自動マージにする。
- 取り消しの 409 や
"status":"error":取り消すものがありませんでした。マージ済みか、取り消し済みか、設定されていなかったかです。マージリクエストのmerge_when_pipeline_succeedsは、設定されている間だけtrueです。
IntelliJ IDEA で GitLab のマージリクエストを見るなら
Lesstep の Merge Request Inbox for GitLab は、JetBrains IDE(2024.1 以降)のプラグインです。マージの前にマージの条件を見せ、画面に出ていた先頭のコミットをマージします。パイプラインが動いている間は、マージのダイアログで自動マージを選べます。auto_merge と merge_when_pipeline_succeeds を両方送るので、17.11 の前と後のどちらの GitLab にも通じます。GitLab がその場でマージしたときは、マージしたと言います。1.0.15 からは、GitLab が自動マージを断ったとき(405)、自動マージはマージの方法が求めるリベースを待たないことと、パイプラインが成功せずにもう終わっているなら自動マージにせずにマージすることを言います。GitLab が答えたのに何も設定していなければ、そう言います。それまでは、ふつうのマージの文を出していました。その文が挙げる下書き・スレッド・承認・パイプラインは、どれも自動マージが待つものです。読むのは無料、承認・コメント・マージは Pro(月 US$1.50・30日間の無料試用つき)です。画面は日本語です。
GITLAB は GitLab Inc. の商標、IntelliJ IDEA は JetBrains s.r.o. の商標です。このページは GitLab Inc.・JetBrains のいずれとも提携しておらず、承認も受けていません。
ほかに:GitLab のマージの断り(400・401・405・409・422) · GitLab のリベースの断り・失敗(403・409) · GitLab の承認の断り(401・409) · GitLab の「insufficient_scope」 · GitLab の 401「invalid_token」 · GitLab の MR の一覧の断り(400・404) · GitLab の MR の変更が欠ける(「1000+」・too_large) · GitLab の 429「Retry later」(回数の上限) · GitLab のスカッシュでマージが断られる・失敗する · GitLab の「compare_timeout」(差分の上限) · JetBrains の IDE で GitLab のマージリクエストを扱う · English