kledgeb Ubuntuの使い方や日本語化、アプリの使い方を紹介しています。

3ウェイマージ

  ブランチブランチマージする際、各ブランチのコミット状況によっては、ファーストフォワードによるマージを行うことができません。

  このようなマージは、「3ウェイマージ」で行います。

ファーストフォワードできない状況

  「ファーストフォワード」によるマージができない状況です。

  以下のように「master」ブランチと「Ver2」ブランチがあり、「master」ブランチに「Ver2」ブランチをマージしようとしています。


  この時、「master」ブランチのブランチヘッドを単純に移動する「ファーストフォワード」によるマージは行えません。
  そもそもブランチヘッドの移動先がありません。

  これは、「master」ブランチと「Ver2」ブランチが「Commit3」で分岐しており、分岐後(ブランチ後)それぞれ異なる変更内容をコミットしているためです。

  ファーストフォワードは利用できない

    もし無理やり「master」ブランチのブランチヘッドを「Ver2」ブランチに持って行ってしまうと、「Commit5」の変更内容が失われてしまいます。

    逆も然りで、「Ver2」ブランチのブランチヘッドを「master」ブランチに持って行ってしまうと、「Commit4」と「Commit6」の変更内容が失われてしまいます。

    従って、単純なブランチヘッドの移動でマージを行う「ファーストフォワード」が利用できない、ということになります。

  3ウェイマージ(3-Way Merge)

    このような状況でマージを行うと、「Git」は3種類の「スナップショット」を使用して「3ウェイマージ」を行います。

  マージコミット(Merge Commit)

    「3ウェイマージ」を行うと、マージ結果を自動的にコミットします。
    従って、新たに「スナップショット」が自動的に生成されます。

    このコミットのことを、「マージコミット」と表現します。
    「マージコミット」の「コミットオブジェクト」は、複数の「親コミットオブジェクト」を持ちます。

  マージコンフリクト(Merge Conflict)

    変更内容によっては、変更内容が衝突する場合があります。

    例えば、AさんとBさんが同じファイルの同じ行を修正したとします。
    この時、どちらの修正内容を適用(採用)すればいいか、「Git」は判断できません。
    この状況を、「マージコンフリクト」といいます。

    「マージコンフリクト」が発生した場合、「Git」はマージを中断し、ユーザーに判断を委ねます。

    ユーザーは、衝突した変更内容を確認してファイルを修正し、自分でコミットを行います。
    「マージコンフリクト」が発生しなかったファイルは、マージが完了している状態になります。

3ウェイマージによるマージ例

  「3ウェイマージ」によるマージ例です。

  1.ブランチの切り替え

   「master」ブランチに「Ver2」ブランチをマージするため、まず「master」ブランチを作業対象に切り替えます。


  2.マージを行う

    「master」ブランチに「Ver2」ブランチをマージします。
    ここから先は、「Git」がマージ処理を行います。

    「Git」はまず、「master」ブランチと「Ver2」ブランチの共通の「コミットオブジェクト」を探します。
    共通の「コミットオブジェクト」とは、分岐直前のコミットオブジェクトのことです。


    「master」ブランチと「Ver2」ブランチの共通の「コミットオブジェクト」は、「Commit3」であることがわかります。

  3.スナップショットを使用してマージを行う

    「Git」は以下の3種類の「スナップショット」を使用してマージを行います。



  4.マージ完了

    マージが完了するとコミットが自動的に行われ、「Commit7」が自動的に生成されます。
    「Commit7」のように、マージにより作成されたコミットを、「マージコミット」と表現します。


    これで「Ver2」ブランチの変更内容が、「master」ブランチにマージされました。

    「Commit7」の「親コミットオブジェクト」は、「Commit5」と「Commit6」になります。
    「Ver2」ブランチがもう不要なら、「Ver2」ブランチを削除するとよいでしょう。

マージの中止とマージコンフリクト

  「3ウェイマージ」は万能ではありません。

  もし上記の「4.スナップショットを使用してマージを行う」の段階で、単純なマージができないケースが存在した場合、マージは行われません。


  これを「マージコンフリクト(Merge Conflict)」といいます。
  コンフリクトは、衝突や矛盾という意味です。

  どちらの変更内容を優先すればよいのか分からない

    例えば、「Commit5」と「Commit6」で同じファイルの同じ箇所が修正されている場合、どちらの内容を優先して採用すればよいのか、「Git」は判断することができません。

    「Commit3」の「readme.txt」に以下のテキストが記述されているとします。

今日の天気は晴れです。

    「Commit5」の「readme.txt」に以下のテキストが記述されているとします。

今日の天気は雨です。

    「Commit6」の「readme.txt」に以下のテキストが記述されているとします。

今日の天気は雪です。

    この時「Commit3」の「readme.txt」は、「Commit5」のテキストを採用すればいいのか、「Commit6」のテキストを採用すればいいのか、どちらがユーザーが期待するテキストなのか「Git」は判断できません。

  マージの中止

    マージする際、「マージコンフリクト」が発生すると、マージ処理を中止します。

    「Git」は「マージコンフリクト」が発生したファイルを把握しており、そのファイルには「コンフリクトマーカー(standard conflict-resolution marker)」が挿入されます。

 
    ユーザーは、「マージコンフリクト」が発生したファイルを編集し、自分でコミットを行います。


    これでマージが完了します。
    

関連コンテンツ
同一カテゴリーの記事
コメント
オプション