コンフリクトのマージ

マージコンフリクトは、マージリクエストの二つのブランチ (ソースとターゲット) にそれぞれ異なる変更があり、どちらの変更を受け入れるかを決めなければならないときに起こります。マージリクエストでは、Gitは2つのバージョンのファイルを一行ずつ比較します。ほとんどの場合、GitLabは変更をマージすることができます。しかし、2つのブランチが同じ行を変更した場合、GitLabはマージをブロックし、どちらの変更を残すかを選択しなければなりません。

マージリクエストは、次のどちらかを行わないとマージできません:

  • マージコミットを作成します。
  • リベースによって競合を解決します。

Merge request widget

ユーザーインターフェイスで解決できるコンフリクト

マージのコンフリクトが以下の条件をすべて満たす場合、GitLab ユーザーインターフェイスでマージのコンフリクトを解決することができます:

  • ファイルがバイナリーではなくテキストであること。
  • ファイルはUTF-8互換のエンコーディングです。
  • ファイルにコンフリクトマーカーが含まれていません。
  • コンフリクトマーカーを追加したファイルのサイズは200KB未満です。
  • ファイルは両方のブランチで同じパスに存在します。

マージリクエストにコンフリクトが含まれているにもかかわらず、これらの条件をすべて満たせないファイルがある場合は、手動でコンフリクトを解決する必要があります。

GitLabが検出できないコンフリクト

GitLabは、両方のブランチがファイル名を異なる名前に変更してもコンフリクトを検出しません。例えば、このような変更はコンフリクトを引き起こしません:

  1. ブランチagit mv example.txt example1.txt
  2. ブランチb で、git mv example1.txt example3.txt

これらのブランチがマージされると、example1.txtexample3.txt の両方が存在することになります。

コンフリクトの解決方法

GitLabはユーザーインターフェイスに解決可能なコンフリクトを表示します。また、コマンドラインを使ってローカルにコンフリクトを解決することもできます:

  • インタラクティブモード:UIモード:編集を行わず、どのバージョンの行を残すかを選択するだけのコンフリクトに最適です。
  • インラインエディター:行を編集し、変更を手動でブレンドする必要のある、より複雑なコンフリクトに最適なUIメソッド。
  • コマンドライン: 最も複雑なコンフリクトを完全にコントロールできます。

対話モードでコンフリクトを解決

GitLabユーザーインターフェイスからそれほど複雑でないコンフリクトを解決するには:

  1. 左のサイドバーで「検索」または「移動」を選択してあなたのプロジェクトを検索します。
  2. コード > マージリクエストを選択し、マージリクエストを見つけてください。
  3. 概要] を選択し、マージリクエストレポートセクションまでスクロールします。
  4. マージコンフリクトメッセージを見つけ、コンフリクトの解決を選択します。GitLab はマージコンフリクトのあるファイルのリストを表示します。コンフリクトはハイライトされています:

    Conflict section

  5. それぞれのコンフリクトについて、Use oursまたはUse theirsを選択して、コンフリクトした行のうち残すバージョンをマークします。この決定を “コンフリクトの解決” と呼びます。
  6. コミットメッセージを入力します。
  7. ソースブランチにコミット を選択します。

コンフリクトを解決すると、選択したバージョンのテキストを使用して、マージリクエストのターゲットブランチがソースブランチにマージされます。ソースブランチがfeature でターゲットブランチがmain の場合、これらのアクションはgit switch feature; git merge main をローカルで実行するのと同じです。

インラインエディターでのコンフリクトの解決

いくつかのマージコンフリクトはより複雑で、コンフリクトを解決するために手動で行を修正する必要があります。GitLab インターフェースで複雑なコンフリクトを解決するには、マージコンフリクト解決エディターを使いましょう:

  1. 左のサイドバーで「検索」または「移動」を選択してあなたのプロジェクトを検索します。
  2. コード > マージリクエストを選択し、マージリクエストを見つけてください。
  3. 概要] を選択し、マージリクエストレポートセクションまでスクロールします。
  4. マージコンフリクトメッセージを見つけ、コンフリクトの解決を選択します。GitLab はマージコンフリクトのあるファイルのリストを表示します。
  5. Edit inlineを選択してエディターを開きます:Merge conflict editor
  6. コンフリクトを解決したら、コミットメッセージを入力してください。
  7. ソースブランチにコミット を選択します。

コマンドラインからコンフリクトを解決

ほとんどのコンフリクトは GitLab ユーザーインターフェイスから解決できますが、中には複雑すぎるものもあります。複雑なコンフリクトは、コマンドラインからローカルで修正するのが一番です:

  1. ターミナルを開き、featureブランチをチェックしてください。例えば、my-feature-branch

    git switch my-feature-branch
    
  2. ブランチをターゲットブランチ (ここではmain) に対してリベースし、Git がコンフリクトの有無を尋ねてくるようにします:

    git fetch
    git rebase origin/main
    
  3. コンフリクトしているファイルをお好みのコードエディターで開きます。
  4. コンフリクトしているブロックを見つけてください:
    • <<<<<<< HEAD というマーカーで始まります。
    • 次に、あなたの変更点が表示されます。
    • マーカー======= は変更の終わりを示しています。
    • 次に、ターゲットブランチの最新の変更点が表示されます。
    • >>>>>>> というマーカーは、コンフリクトの終了を示しています。
  5. ファイルを編集します:
    1. どちらのバージョン(======= の前または後)を保持するかを選択します。
    2. 保存したくないバージョンは削除してください。
    3. コンフリクトマーカーを削除します。
  6. ファイルを保存してください。
  7. コンフリクトを含む各ファイルについて、このプロセスを繰り返します。
  8. Git で変更をステージします:

    git add .
    
  9. 変更をコミットします:

    git commit -m "Fix merge conflicts"
    
  10. リベースを続行します:

    git rebase --continue
    
    caution
    この時点までは、git rebase --abort を実行して処理を止めることができます。Git はリベースを中止し、ブランチをgit rebaseを実行する前の状態にロールバックします。git rebase --continueを実行した後は、リベースを中止することはできません。
  11. 変更をリモートブランチに強制プッシュします。

マージコミット戦略

GitLabはソースブランチにマージコミットを作成することでコンフリクトを解決しますが、ターゲットブランチにはマージしません。マージコミットをレビューしてテストすることができます。意図しない変更が含まれておらず、ビルドが壊れていないことを確認してください。