GitLabのマージリクエスト(MR)は、ブランチの変更をmainなどへ取り込む前に、差分のレビュー・承認・CIの結果を1画面にまとめる機能です。この記事では、MRの作り方を画面操作とgit pushのオプションの両方で示し、そのうえで承認ルール、承認設定、マージチェック、自動マージ、マージ方式の設定手順を解説します。Freeでは承認が任意にとどまる点や、CODEOWNERSとAPIで複数プロジェクトへ同じ設定を配る方法も解説の対象です。画面名と既定値は2026年11月時点の公式ドキュメントにもとづいています。
まとめ:GitLabのマージリクエストは承認・マージ条件・方式の3設定で固める
MRを作るだけなら、どのプランでも画面かgit push -o merge_request.createで済みます。運用の質を決めるのは、作った後に「誰の承認があればマージできるか」「何が通らなければマージさせないか」「マージ後の履歴をどの形にするか」の3つの設定です。
承認をマージの条件として強制できるのはPremium以上で、Freeの承認は記録にとどまります。Freeのチームでも、マージチェックの「Pipelines must succeed」と「All threads must be resolved」は使えるので、まず有効にするのはこの2つです。承認必須は、本番へ直結するブランチを複数人で触るチームに限って入れ、2人以下のチームでは見送る判断で足ります。
GitLabのマージリクエストとは:プルリクエストとの違いとFreeでできる範囲
MRの定義とGitHubのプルリクエストとの呼び名・機能の対応関係
GitLabのMerge requestsのドキュメントは、MRをコードの変更をブランチへ取り込むための提案と位置づけ、差分、コメントのスレッド、パイプラインの結果、承認の状態を同じ画面に集めています。GitHubのプルリクエストと役割は同じで、名前が違うのは「取り込み先へのマージを依頼する」側の操作に注目した呼び方だからです。
GitHub側の作成手順とレビュー必須化はGitHubのPull Requestの作り方とレビュー必須化の決め方で解説しています。
Free・Premium・Ultimateで変わるMR機能の対応表と承認の扱い
MRの基本機能は全プランで使えますが、承認まわりはプランで扱いが変わります。承認のドキュメントは、FreeではDeveloper以上の全員が承認でき、その承認は任意でマージを妨げないと明記しています。
| 機能 | Free | Premium・Ultimate |
|---|---|---|
| MRの作成・レビュー・承認ボタン | 使える | 使える |
| 承認をマージの条件にする | 不可(任意) | 承認ルールで可 |
| CODEOWNERSによる承認 | 不可 | 可 |
| MRの担当者(Assignee) | 1人まで | 複数人 |
| マージチェック・自動マージ | 使える | 使える |
| マージ方式・スカッシュ設定 | 使える | 使える |
担当者の人数制限はMRのドキュメントの「On GitLab Free, you can assign one user per merge request.」という記述によります。2026年11月時点の料金ページではPremiumが年額契約で1ユーザー月29ドル、Ultimateは個別見積もりです。承認必須だけのためにPremiumへ上げるかどうかは、後半の判断の章で扱います。
マージリクエストを作成する手順:画面操作・git pushオプション・テンプレート
画面からMRを作るときに決めるソース・ターゲット・ドラフトの入力項目
画面から作る場合は、ブランチをpushした直後にプロジェクト上部へ出る作成ボタンを使うか、左サイドバーのMerge requestsから新規作成します。入力で迷いやすいのは4項目です。
- ソースブランチとターゲットブランチ:ターゲットは既定ブランチが初期値なので、リリースブランチ宛てなら必ず変える
- タイトルと説明:説明に
Closes #12と書くと、既定ブランチへのマージ時にIssueが閉じる - Mark as draft:レビュー前の途中段階なら選ぶ
- Delete source branch when merge request accepted:マージ後の作業ブランチを自動で消す
ドラフトのドキュメントによると、タイトルの先頭にDraft:・[Draft]・(Draft)のどれかを付けても同じ扱いになり、ドラフトの間は他の条件を満たしていてもマージできません。IssueからブランチとMRを同時に作る流れは、親記事のGitLabの使い方(プロジェクト作成からIssue・MR・CI/CDまで)で手順を追っています。
git push -oでMR作成と自動マージ・ラベル付与を1コマンドで済ませる例
ブラウザを開かずにMRを作るなら、push optionsのドキュメントにあるmerge_request.*のオプションを並べます。-oは複数回指定でき、値に空白を含むときはダブルクォートで囲みます。
# feature/login-rate-limit を push し、main 宛ての MR をドラフトで作る
git push -u origin feature/login-rate-limit \
-o merge_request.create \
-o merge_request.target=main \
-o merge_request.title="ログイン試行回数の上限を追加" \
-o merge_request.draft \
-o merge_request.label="backend" \
-o merge_request.remove_source_branch \
-o merge_request.squash
# レビュー後、条件がそろったら自動でマージさせる(同じブランチへの追加 push で付与)
git push -o merge_request.auto_merge
同ドキュメントでは、自動マージの旧オプションmerge_request.merge_when_pipeline_succeedsがGitLab 17.11で非推奨となり、merge_request.auto_mergeが後継です。merge_request.squashは17.2で追加されたオプションなので、古いSelf-Managedでは効きません。既定ブランチから直接pushする場合はmerge_request.targetの指定が必須になります。
Default.mdのMRテンプレートで説明欄の書き方を揃えるファイル配置
MRの説明が人によって薄くなる問題は、テンプレートで防ぐ運用が可能です。Description templatesのドキュメントによると、リポジトリの.gitlab/merge_request_templates/にMarkdownファイルを置くと、作成画面のChoose a templateから選べます。ファイル名をDefault.md(大文字小文字は区別しない)にすると、新しいMRの説明欄へ最初から入ります。
<!-- .gitlab/merge_request_templates/Default.md -->
## 変更内容
-
## 関連 Issue
Closes #
## 確認方法
1.
2.
## レビュー観点
- [ ] DB マイグレーションの有無を説明欄に書いた
- [ ] 画面変更がある場合はスクリーンショットを添付した
- [ ] 設定値・環境変数の追加をデプロイ手順に反映した
プロジェクト設定画面で既定テンプレートを選ぶ方法はPremium・Ultimate向けですが、Default.mdを置く方法にはプランの制限が書かれていません。レビューで何を見るかの決め方はコードレビューの目的・観点と運用設計が参考になります。
マージリクエストの承認ルール設定:必要承認数・承認者・コードオーナー
Approval rulesで対象ブランチと必要承認数を決める画面の操作順
承認ルールはPremium以上の機能で、設定にはプロジェクトのMaintainerかOwnerのロールが要ります。承認ルールのドキュメントの手順は次のとおりです。
- 左サイドバーでSettings > Merge requestsを開く
- Merge request approvalsのApproval rulesでAdd approval ruleを選ぶ
- Target branchでAll protected branchesか特定のブランチを選ぶ
- Approvals requiredに必要な承認数を入れる(0で任意、1以上で必須、上限100)
- Add approversで承認者のユーザーかグループを指定し、Save changesで保存する
承認者が複数のルールに属している場合、1回の承認で全ルールの残り数が減ります。グループを承認者にしたとき、親グループから継承したメンバーは承認者に数えられません。
CODEOWNERSのセクション記法でディレクトリごとに承認者を割り当てる例
「DBのマイグレーションはDBチーム、インフラ定義はSREが必ず見る」のように、変更したファイルで承認者を変えたいときはCODEOWNERSを使います。Code Ownersのドキュメントによると、ファイルはリポジトリ直下、docs/、.gitlab/の順に探され、最初に見つかったものが使われます。
# .gitlab/CODEOWNERS
# 既定の所有者:どのファイルの変更にも 1 人の承認を求める
* @dev-leads
# DB 関連は DB チームから 2 人の承認が必要
[Database][2] @example-org/db-team
db/migrate/
app/models/
# インフラ定義は SRE が承認
[Infrastructure] @example-org/sre
/terraform/
/.gitlab-ci.yml
# ドキュメントは任意のセクション(承認が無くてもマージ可)
^[Docs] @example-org/tech-writers
/docs/**/*.md
CODEOWNERSの構文リファレンスでは、[Section][2]で承認数を、先頭の^で任意セクションを表します。承認数とセクションの既定所有者が効くのは保護ブランチ宛てのMRだけです。CODEOWNERSの承認を必須にするには、保護ブランチの設定でRequired approval from code ownersを有効にする必要があり、ファイルを置いただけでは承認者の表示にとどまります。
承認設定の既定値と作成者承認・push時リセットの4項目の選び方
承認ルールと別に、Settings > Merge requestsのApproval settingsで承認の扱いを決めます。承認設定のドキュメントに書かれた既定値と、変える目安を表にしました。
| 設定 | 既定 | 変える目安 |
|---|---|---|
| 作成者による承認 | 不可 | そのまま |
| コミットした人の承認 | 可 | ペア作業が多いなら禁止 |
| MRごとのルール上書き | 可 | 監査対象なら禁止 |
| 追加コミット時の承認 | 全承認を削除 | そのまま |
実務で触るのは主に2つです。1つ目のPrevent editing approval rules in merge requestsは、作成者がMR上で承認者を減らす抜け道をふさぐ設定で、承認の記録を監査に出す組織では有効にします。2つ目は追加コミット時の扱いで、既定の「承認後に変更を足すと承認が消える」動きは残すほうが安全です。Code Ownerの担当ファイルが変わったときだけ消す選択肢もありますが、承認後に別ファイルへ足された変更が誰にも見られずに入る余地が残ります。設定はインスタンス、トップレベルグループ、プロジェクトの順に効き、上位で有効にした禁止設定は下位で変えられません。
承認ルールと承認設定をAPIで複数プロジェクトへ一括適用するcurl例
プロジェクトが10を超えると、画面で同じ設定を繰り返すよりMerge request approvals APIで配るほうが漏れません。ルールの作成はPOST /projects/:id/approval_rules、承認設定の変更はPOST /projects/:id/approvalsで、どちらもPremium以上が対象です。
# GITLAB_TOKEN(api スコープ)と対象プロジェクト ID を用意しておく
GITLAB=https://gitlab.example.com/api/v4
for PID in 101 102 103; do
# 保護ブランチ全体に「2 人承認」のルールを作る
curl --request POST \
--header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \
--header "Content-Type: application/json" \
--data '{"name":"2 approvals","rule_type":"any_approver","approvals_required":2,"applies_to_all_protected_branches":true}' \
"${GITLAB}/projects/${PID}/approval_rules"
# 作成者・コミッターの承認を禁止し、MR 上でのルール上書きも禁止する
curl --request POST \
--header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \
--data "merge_requests_author_approval=false" \
--data "merge_requests_disable_committers_approval=true" \
--data "disable_overriding_approvers_per_merge_request=true" \
--data "reset_approvals_on_push=true" \
"${GITLAB}/projects/${PID}/approvals"
done
APIの記述では、承認数の旧パラメータapprovals_before_mergeが12.3で、require_password_to_approveが16.9で非推奨になっています。古いスクリプトを流用するときはこの2つが置き換えの対象です。ボットがMRを承認する場合はPOST /projects/:id/merge_requests/:merge_request_iid/approveにshaを付けると、HEADが変わっていれば409が返り、見ていないコミットを承認する事故を防げます。
マージの条件と方式を決める設定:マージチェック・自動マージ・履歴の形
マージチェック2項目でCI失敗と未解決スレッドのMRを止める設定
Freeでも使える歯止めがマージチェックです。Settings > Merge requestsのMerge checksで、Pipelines must succeedを選ぶとパイプラインが成功しないMRはマージできなくなります。All threads must be resolvedを選ぶと、未解決のコメントスレッドが残るMRのマージが止まります。
見落としやすいのは、Pipelines must succeedを有効にしたプロジェクトでパイプラインが1本も走らないMRです。公式ドキュメントは「パイプラインが全く無いMRは成功したパイプラインを持つとはみなされず、マージできない」としています。.gitlab-ci.ymlのrulesで全ジョブが除外されるMRがあるなら、併せてSkipped pipelines are considered successfulを選ぶか、MRでは必ず1ジョブ走るようにします。
MRパイプラインをrulesで設定しブランチパイプラインとの二重起動を防ぐ
MRのときにテストを走らせるには、Merge request pipelinesのドキュメントにある$CI_PIPELINE_SOURCE == "merge_request_event"の条件を使います。ブランチへのpushでもパイプラインが走る設定のままだと、MRのあるブランチで2本ずつ起動して計算時間を倍に食うため、workflowのドキュメントにある$CI_OPEN_MERGE_REQUESTSを使った振り分けを入れます。
# .gitlab-ci.yml
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event" # MR では MR パイプライン
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
when: never # MR があるブランチの push では走らせない
- if: $CI_COMMIT_BRANCH # MR の無いブランチと main へのマージ後は走らせる
test:
stage: test
script:
- npm ci
- npm test
include:componentなど外部から読み込んだrulesでは条件を満たさないため、.gitlab-ci.yml本体に書きます。rulesやneedsの書き方全般はGitLab CI/CDの.gitlab-ci.ymlの書き方とrulesの設定例にまとめています。
Set to auto-mergeで承認とCI完了を待ってマージさせる操作と取り消し
レビューは済んだがパイプラインがまだ走っている、という待ち時間はauto-mergeで消せます。MRの画面でSet to auto-mergeを選ぶと、条件がそろった時点でGitLabがマージします。Auto-mergeのドキュメントが挙げる待ち条件のうち、日常的に効くのは次の5つです。
- 必要な承認がすべてそろっている
- パイプラインが成功している(プロジェクト設定にかかわらず必要)
- すべてのスレッドが解決している
- ドラフトではなく、コンフリクトも無い
- 他のMRによるブロックが無い
拡張版のauto-mergeは16.5で機能フラグ付きで入り、17.7で一般提供になりました。取り消すときはMRのレポート欄でCancel auto-mergeを選ぶ操作が必要です。パイプラインが失敗した場合、失敗したジョブの再実行が成功すればそのままマージされます。一方で新しいコミットを追加するとGitLabがauto-mergeを取り消すため、修正をpushした後は設定し直します。
マージ方式3種とスカッシュ4段階の組み合わせで決まるmainの履歴
マージ後のmainの履歴の形は、Merge methodsのドキュメントにある2つの設定の組み合わせで決まります。マージ方式はMerge commit(既定)、Merge commit with semi-linear history、Fast-forward mergeの3種です。スカッシュはSquash commits when mergingでDo not allow・Allow・Encourage・Requireの4段階から選びます。
| 組み合わせ | mainの履歴 | 向くチーム |
|---|---|---|
| Merge commit+Allow | MRごとにマージコミット | MR単位で戻したい |
| semi-linear+Encourage | 直線に近く区切りが残る | 履歴を読む機会が多い |
| Fast-forward+Require | 1MR=1コミットの直線 | 小さいMRを高頻度で出す |
semi-linearとFast-forwardでは、ソースブランチがターゲットの最新を取り込んでいないとマージできません。コンフリクトが無ければMRのRebaseボタンか/rebaseで済みますが、Enable automatic rebase prior to mergeでのサーバー側rebaseはパイプラインを再実行せず、GPG署名も外れます。署名付きコミットを求める組織ではFast-forwardを避けるか、ローカルでrebaseする手順への固定が必要です。スカッシュ後の履歴の扱いはgit squashの手順とスカッシュマージの注意点、rebaseとmergeの違いはgit rebaseの使い方とmergeとの違いで詳しく扱っています。
MRの承認を必須にする条件と見送る場面:チーム規模とプランで判断
Premiumで承認必須にすべき条件:本番直結ブランチと外部委託の混在
承認必須のためにPremiumを契約してよいのは、次のどちらかに当てはまるときです。1つは、mainやproductionへのマージがそのまま本番デプロイにつながり、レビューを飛ばしたマージが障害に直結する構成が該当します。もう1つは、社員と外部委託先が同じリポジトリに書き込み、委託先の変更を社内の誰かが必ず見たという記録を残す必要がある場合です。
この2条件では、承認ルール1本(保護ブランチ全体に1〜2人)と、作成者・コミッターの承認禁止、MR上でのルール上書き禁止をセットで入れます。どれか1つを欠くと、自分の変更を自分で通す道が残るためです。環境ブランチを使ってmainと本番を分けているなら、GitLab Flowの環境ブランチの組み方と合わせて、昇格用MRにだけ承認を課す設計も選べます。
承認必須を見送る場面:2人以下のチームと形だけの承認になる失敗パターン
開発者が2人以下のチームでは、承認必須は入れません。作成者の承認が禁止されているため、相手が休んだ日はマージが止まり、結局は設定を外すか管理者権限で迂回する運用に落ちます。この規模なら、Freeのまま「Pipelines must succeed」「All threads must be resolved」と保護ブランチで十分です。
人数が多くても失敗はあります。典型的な失敗は次の2つに分かれます。1つ目は承認者をグループ全体にして承認数を1にした結果、差分を開かずにApproveを押す承認が常態化するパターンです。2つ目はCODEOWNERSの*に少数の担当者だけを置き、その人のレビュー待ちでMRが滞るパターンです。前者はCODEOWNERSで領域ごとに承認者を絞り、後者は任意セクションの^で必須の範囲を減らして解消します。AIによる一次レビューを挟んで人の負担を減らす方法はPR-AgentをGitLabで使う手順で扱っています。
承認ルールやマージチェックを、CIの設計や保護ブランチと合わせて組み直したい場合は、一創のDevOps・CI/CD導入支援で、現在のプランとリポジトリ構成を確認したうえで設定案と移行手順を作成できます。ブランチ戦略から見直すならGit運用のベストプラクティス(ブランチ戦略とレビュー基準)が入口です。
よくある質問
GitLabのマージリクエストについて、設定の段階でよく出る質問をまとめました。
GitLabのマージリクエストはFreeプランでも承認できますか?
承認すること自体はできます。FreeではDeveloper以上のロールを持つ全員がApproveを押せて、承認の記録もMRに残ります。ただし承認は任意の扱いで、承認が無くてもマージは止まりません。承認をマージの条件にするにはPremium以上の承認ルールが要ります。
承認したマージリクエストの承認を取り消すことはできますか?
取り消せます。承認済みのMRではウィジェットのボタンがRevoke approvalに変わり、選ぶと承認が外れる仕組みです。承認数がルールの必要数を下回れば、そのMRは再びマージできない状態に戻ります。
承認された後にコミットを追加すると承認はどうなりますか?
既定では承認が消えます。公式ドキュメントは「承認後に変更を足すと、MRの承認は削除される」と既定の動きを説明しています。設定で承認を残すこともできますが、承認者が見ていないコードがマージされるため勧めません。
ドラフトのマージリクエストを解除するにはどうすればよいですか?
MRの画面右上でMark as readyを選ぶか、コメントに/readyと入力します。タイトル先頭のDraft:などを消しても解除されます。注意点はコミットメッセージで付けたドラフトで、Draft:やfixup!で始まるコミットを積んでドラフトになった場合、後のコミットで同じ文言を書いても解除はされません。
マージリクエストのMergeボタンが押せないのはなぜですか?
マージの条件のどれかが満たされていないためです。よくある原因は、ドラフトのまま、必要な承認が不足、パイプラインが失敗または1本も走っていない、未解決のスレッドが残っている、ターゲットとのコンフリクト、Fast-forwardやsemi-linearでrebaseが必要、の6つです。満たしていない条件はMRのウィジェットに表示されます。
関連記事
- GitLabの使い方:プロジェクト作成からIssue・MR・CI/CDまでの手順【2026年10月】:MRを含むGitLabの基本操作を最初から1周したいときの入口です
- GitLabとは:構成要素・CEとEEの違い・3つの提供形態とDockerで試す手順【2026年11月】:承認ルールが使えるプランと提供形態の違いを確認できます
- GitHubとGitLabの違い|ActionsとGitLab CIの対応表・料金・セルフホスト比較:MRとプルリクエストを含めてサービス自体を比べたいときに役立ちます
- GitHubのPull Requestの作り方:作成手順とマージ方式・レビュー必須化の決め方:GitHub側で同じ承認とマージの設定をする場合の手順です
- コードレビューとは?目的・観点・進め方と実装現場の運用設計を解説:MRで何をレビューするかの観点づくりに使えます