解 説

今回の内容で特にマージをした時にコンフリクトを起こしてしまう状況を考えてみます。
Git初心者で実務でコンフリクトを起こすと焦ってしまうに違いありません。日頃からGitを使い倒しておくと焦ることはないでしょう。
ココは何度も失敗をしてこれはやっちゃダメとかいうことを身をもって学習することです。

今回覚えておきたい用語
ブランチ:履歴の流れを分岐すること
マージ:分岐した履歴を統合すること
コンフリクト:同じ箇所に別の内容が競合すること

ブランチ

ブランチとは枝という意味があります。その名前のとおり複数の作業を枝分かれする時に使います。
具体的には、同時に複数の作業を行う場合などにブランチを使います。

ここでは参考例として「task-A」と「task-B」2つのブランチを作成します。

新規にブランチを作成するにはブランチボタンをクリックします。「新規ブランチ」項目に任意の新しいブランチの名前を記入します。「新規ブランチをチェックアウト」にチェックが入っていると、ブランチ作成と同時そのブランチがチェックアウト(選択された)状態になります。
今回は「task-A」というブランチを作成します。
git301

左側のメニューに新しく「task-A」のブランチができます。
git302

ここで「task-A」のブランチが選択されていることを確認します。もし選択されてなければ右クリックして「〜をチェックアウト」を選びます。
「Task-A」ブランチの状態でsample.htmlを編集します。
今回は、p要素に今回は「Task-A」の作業をしたことがわかるように、task-Aとだけ記述しました。

HTMLコード

その後SourceTree画面上でステージングエリアに移動してコミットします。
git303

ここで一旦「master」ブランチをチェックアウトします。
その後、もうひとつブランチを作成するには先程と同様にブランチボタンをクリックして「task-B」を作成します。
git304

左側のブランチの項目で「task-B」が選択されていることを確認し、されてなければ「task-B」でチェックアウトします。
そしてsample.htmlを編集します。sample.htmlには「task-A」で編集した内容はありません。これはブランチが変わっているためです。
ここではp要素に作業例としてtask-Bと記述しました。

HTMLコード

その後SourceTree画面上でステージングエリアに移動してコミットします。
git305

マージする方法

枝分かれしたブランチを統合することをマージと呼びます。
ブランチ「task-A」とブランチ「task-B」をもとのmasterに統合します。

まずは「task-A」を「master」に統合します。
一旦「master」を選択して右クリックメニューからチェックアウトします。これで「marge」が選択された状態になりました。
git306

上にあるマージボタンをクリックするとマージのパネルが出てきます。
どのブランチとマージするか選択してOKボタンをクリックします。ここでは「task-A」を選んでOKをクリックします。
git307

次に今度はブランチ「task-B」をマージします。先程と同様の手順で実施します。
git308

今度は「マージで競合」と警告が出ます。
git309
とりあえず、OKボタンをクリックします。

それから編集しているsample.htmlのコードを確認すると次のようになっています。

HTMLコード

ブラウザで表示すると意味不明な表示になります。特にJavaScriptなどのスクリプトでこの状況になるとエラーになり、大変焦ってしまう結果になるのです。

コンフリクト

この状態がコンフリクト(衝突)を起こした状態です。
この状況は頻繁に起こります。Git初心者泣かせのものです。

では、なぜこのようなコンフリクトが起こってしまったのでしょうか、原因をさぐってみます。

今回のsample.htmlの編集は非常にシンプルなものです。
bodyの中にpタグで囲んだtask-Aとpタグで囲んだtask-Bを追加したものでした。
ただし、追加の方法として2手に分かれて記述をしました。

task-Aの記述はブランチ「task-A」を作成して作業を行い、task-Bの記述はブランチ「task-B」を作成して作業を行いました。
ポイントはそれぞれの作業は並行して行われ、どちらも開始したときはbodyの中身は空っぽだったことです。

そして最初にブランチ「task-A」をマージして作業をmasterと合体しました。この時は何も問題ありませんでした。
ところが、次にブランチ「task-B」をマージした時に衝突が起こりました。

原因はブランチ「task-B」をマージにあるようです。
なぜ、衝突を起こしたのか?

それはブランチ「task-B」を開始した時の状態です。このときもbody要素は空っぽでした。当然「task-A」の内容もありません。
bodyタグの次には「task-B」の内容が続くはずです。
ところが、「master」とマージして合体したときbodyタグの次には「task-A」の内容がすでに鎮座しているのです。
それで、「task-B」の記述をしようとするとそこにはすでに「task-A」がある。同じ場所に違う内容を記述する場面で、コンピュータは処理に困り衝突したと言って知らせてくるのです。

そしてこれはエラーではなく、当たり前に日常的に起こることです。
ブランチを分けて作業を行ったり、リモートリポジトリとローカルリポジトリをプッシュ、プルするときにも起こります。

そしてGitではどうしてよいか判断がつかないので独特の表現で答えを出してきます。

その表現が先程のHTMLコードの以下の部分になります。

<<<<<<< HEAD から ======= までの内容と、======= から >>>>>>> task-B までの内容が衝突しているけれどもどうするのですか?と我々に問いかけて来ています。この辺の判断は自分でしてねということです。

marge1

従って「task-A」の作業者と「task-B」の作業者は協議の上どちらかを残すか、または両方残すけれども順番はどうするかを決めて最終調整する必要があります。そしてその際に、<<<<<<< HEAD や、=======、>>>>>>> task-Bをきれいに削除しておきます。

新人でしかもGit初心者だと大体ここで青くなりますね。
パニックになって色々と変な操作をすると泥沼にはまります。
普通の新人は先輩よりも作業が遅いはずですからコンフリクトに出会いやすいかも。。。

コンフリクトしたときの処置は会社で手順が決まっていると思いますので先輩に確認しましょう。

マージすればコンフリクトは当たり前と知っていれば焦ることはないですよね。

Gitの関連記事