マージ方法

プロジェクトで選択したマージ方式によって、マージリクエストの変更が既存のブランチにマージされる方法が決まります。

このページの例では、コミット A、C、E のmain ブランチと、コミット B、D のfeature ブランチを想定しています:

gitGraph commit id: "A" branch feature commit id: "B" commit id: "D" checkout main commit id: "C" commit id: "E"

プロジェクトのマージ方法の設定

  1. 左のサイドバーで「検索」または「移動」を選択してあなたのプロジェクトを検索します。
  2. 設定 > マージリクエストを選択します。
  3. これらのオプションから希望のマージ方法を選択します:
    • コミットのマージ
    • セミリニアヒストリーを含むマージコミット
    • 早送りマージ
  4. マージ時のSquashコミットで、コミットを処理するデフォルトの動作を選択します:
    • Do not allow:許可しない: Squashは実行されず、ユーザーは動作を変更できません。
    • 許可します:スクワッシングはデフォルトではオフですが、ユーザーは動作を変更できます。
    • Encourage:スクワッシングはデフォルトでオンですが、ユーザーが動作を変更できます。
    • Require:スクワッシングは常に実行され、ユーザーは動作を変更できません。
  5. 変更を保存を選択します。

コミットのマージ

デフォルトでは、GitLab はブランチをmain. mainNET にマージするときにマージコミットを作成します。mainマージ時にコミットをつぶすかどうかにかかわらず、常に別のマージコミットが作成されます。この方式では、ブランチにスクワッシュコミットとマージコミットの両方 mainが追加されることになります。

これらの図は、マージコミット戦略を使用した場合にfeature ブランチがmain ブランチにマージされる様子を示しています。これらは、コマンドgit merge --no-ff <feature> を実行し、GitLab UI でマージ方法として Merge commit を選択した場合と同じです:

マージ戦略

%%{init: { 'gitGraph': {'logLevel': 'debug', 'showBranches': true, 'showCommitLabel':true,'mainBranchName': 'main'}} }%% gitGraph commit id: "A" branch feature commit id: "B" commit id: "D" checkout main commit id: "C" commit id: "E" merge feature

機能ブランチをマージコミットでマージすると、main ブランチはこのようになります:

%%{init: { 'gitGraph': {'logLevel': 'debug', 'showBranches': true, 'showCommitLabel':true,'mainBranchName': 'main'}} }%% gitGraph commit id: "A" commit id: "C" commit id: "E" commit id: "squash commit" commit id: "merge commit"

これに対して、スカッシュマージはブランチのすべてのコミットを仮想的にコピーしたスカッシュコミットを作成しますfeature 。元のコミット (B と D) は featureブランチfeature 上で変更されずに feature残り、スクワッシュコミットはmain ブランチに置かれます:

%%{init: { 'gitGraph': {'showBranches': true, 'showCommitLabel':true,'mainBranchName': 'main'}} }%% gitGraph commit id:"A" branch feature checkout main commit id:"C" checkout feature commit id:"B" commit id:"D" checkout main commit id:"E" commit id:"squash commit" type: HIGHLIGHT

スカッシュマージのグラフは、GitLab UI のこれらの設定と同じです:

  • マージ方法:マージコミット。
  • マージ時のスクワッシュコミットは、以下のいずれかに設定します:
    • 必須
    • Allow または Encourage のいずれかと、squashing をマージリクエストで選択する必要があります。

squashマージグラフもこれらのコマンドと同等です:

git checkout `git merge-base feature main`
git merge --squash <feature>
SOURCE_SHA=`git rev-parse HEAD`
git checkout <main>
git merge --no-ff $SOURCE_SHA

セミリニアヒストリーを含むマージコミット

マージコミットはマージごとに作成されますが、ブランチは早送りマージが可能な場合にのみマージされます。これにより、マージリクエストのビルドが成功した場合、マージ後のターゲットブランチのビルドも成功するようになります。このマージ方式で作成されたコミットグラフの例です:

gitGraph commit id: "Init" branch mr-branch-1 commit commit checkout main merge mr-branch-1 branch mr-branch-2 commit commit checkout main merge mr-branch-2 commit branch squash-mr commit id: "Squashed commits" checkout main merge squash-mr

Merge commit with semi-linear history 方式を選択した状態でマージリクエストページにアクセスすると、早送りマージが可能な場合にのみ、そのマージリクエストを受け入れることができます。早送りマージが不可能な場合、ユーザーにはリベースするオプションが与えられます。

この方法は、マージコミット方式と同じ Git コマンドと同じです。しかし、ソースブランチがターゲットブランチの古いバージョン (main など) に基づいている場合は、ソースブランチをリベースする必要があります。このマージ方式では、すべてのブランチがどこから始まってマージされたのかを確認しながら、よりすっきりとした見た目の履歴を作成することができます。

早送りマージ

ワークフローポリシーによって、マージコミットのないクリーンなコミット履歴が求められることがあります。そのような場合は、fast-forward マージが適切です。fast-forward マージリクエストを使えば、マージコミットを作成せずにマージリクエストを受け付けることができます。このマージ方式で作成したコミットグラフの例です:

gitGraph commit id: "Init" commit id: "Merge mr-branch-1" commit id: "Merge mr-branch-2" commit id: "Commit on main" commit id: "Merge squash-mr"

この方法は、通常のマージではgit merge --ff <source-branch> と、スカッシュマージではgit merge --squash <source-branch> と同等です。

fast-forward merge (--ff-only) の設定が有効な場合、マージコミットは作成されず、すべてのマージが fast-forward されます。マージは、ブランチを fast-forward できる場合にのみ許可されます。fast-forward マージができない場合、ユーザーにはリベースするオプションが与えられます。(semi-)linear merge methods におけるリベースを参照ください。

note
マージコミットが作成されないため、fast-forward マージ戦略を使用しているプロジェクトでは、デプロイ日によるマージリクエストのフィルタリングはできません。

Fast-forward merge 方式が選択された状態でマージリクエストページにアクセスすると、早送りマージが可能な場合のみ、それを受け入れることができます。

Fast-forward merge request

(半)線形マージメソッドにおけるリベース

これらのマージ方式では、ソースブランチがターゲットブランチと最新である場合にのみマージできます:

  • セミリニアヒストリによるマージコミット。
  • マージを早送りします。

早送りマージはできないが、コンフリクトのないリベースは可能な場合、GitLabは提供します:

両方の条件が true の場合、早送りマージの前にローカルでソースブランチをリベースする必要があります:

  • ターゲットブランチがソースブランチより先にある場合。
  • 競合のないリベースはできません。

Fast forward merge rebase locally

リベースはスクワッシュの前に必要かもしれませんが、たとえスクワッシュ自体がリベースと等価であってもです。

CI/CDパイプラインなしのリベース

CI/CD パイプラインをトリガーせずにマージリクエストのブランチをリベースするには、マージリクエストレポートセクションからパイプラインなしでリベースを選択します。このオプションは、早送りマージはできないがコンフリクトのないリベースは可能な場合に利用できます。

CI/CD パイプラインなしのリベースは、頻繁なリベースが必要なセミリニアワークフローのプロジェクトのリソースを節約します。