コンフリクトを知って、体験して、解決しよう

概要

最終更新日:2020/02/11

この記事ではバージョン管理で最も気をつけなければいけない内容の一つである
コンフリクトについて書いています。
コンフリクトを知って、体験してもらって、解決するまでの流れを書いています。

コンフリクトとは

コンフリクトとは自分の変更と他の人の変更箇所が重複することによって
更新ができない状態のことです。

git_0109

差分チェック

Gitはファイル単位で変更履歴を管理しているのではなく、
変更箇所の差分で管理をしています。
以下のように同じファイルであっても、修正場所が異なるなら
コンフリクトは発生しません。

git_0111

コンフリクトは修正箇所が同じ場所と判断されたときに発生します。

解決方法

コンフリクトの基本的な解決方法は以下の通りです。
  • 開発側で重複している箇所を修正する
Gitでは重複している部分を見つけてもどちらの変更が正しいのか分かりません。
その為、解決は開発側で修正を行う必要があります。

実践

コンフリクトの発生から修正までの流れを実践します。
  1. リポジトリを用意してファイルを追加
  2. ローカルリポジトリをもう一つ用意する
  3. B側:ファイルを変更する
  4. A側:ファイルを変更する
  5. A側:プルをしてコンフリクトさせる
  6. A側:ログが増えたことを確認する
  7. A側:コンフリクトを確認する
  8. A側:コンフリクトを修正する
  9. A側:修正をコミットする
  10. A側:プッシュして終了

リポジトリを用意してファイルを追加

まず、コンフリクト用のリポジトリを用意して、テキストファイルを一つ追加します。
次は追加したテキストファイルに適当な文章を入力してから、プッシュしてください。

git_0098

ローカルリポジトリをもう一つ用意する

コンフリクトを発生させるために、もう一つローカルリポジトリを作成してください。
リモートリポジトリが同じローカルリポジトリの作り方はリポジトリをクローンする際に
リポジトリ名とフォルダの作成場所を変えれば作れます。

git_0099

記事では「ConflictPracticeA」「ConflictPracticeB」と名付けていますが
これ以降は省略して「A」と「B」と書きます。

B側:ファイルを変更する

次はB側のファイルを変更をしてプッシュします。
こちらの変更に関しては指定はありません。

git_0100

A側:ファイルを変更する

B側のプッシュが終わったら、A側のファイルを変更してコミットします。
変更はB側で変更した場所と同じ場所を変更してください。
※変更前にA側でプルはしないでください

git_0101

A側:プルをしてコンフリクトさせる

プルを行うとコンフリクトが発生したことを通知するウィンドウが表示されます。

git_0103

A側:ログが増えたことを確認する

コンフリクトが発生すると「コミットされていない~」のログが追加されます。
この時のステータスアイコンはコンフリクト用のものが使用されます。

git_0104

A側:コンフリクトを確認する

コンフリクトファイルの確認をします。

git_0105

コンフリクトしたファイルはGitによって場所が分かるように書き換えられています。
「<<<<<<<<<<<HEAD」から「=====」まで(①)がプルを行った側のリポジトリの変更です。
「=====」から「>>>>>>>>>> 文字列」まで(②)がリモートリポジトリ側の変更です。
>>>>>の後にある文字列の部分はコンフリクトしているコミットのIDです。

A側:コンフリクトを修正する

コンフリクトの修正は状況によって異なりますが、
以下のどちらかの方法をとることが多いです。
  • どちらかの変更のみを使用する
  • 二つの変更を統合する

今回は二つの内容を統合する形で修正しています。

git_0106

A側:修正をコミットする

修正したコンフリクト部分をコミットすると、コンフリクトで出来なかった
プルが自動で実行されて、その結果プルアイコンの数字が消えます。
また、A側でファイル変更したコミットと、コンフリクト修正のコミットの
二つのコミットがプッシュアイコンの隣に表示されます。

git_0107

A側:プッシュして終了

最後に修正したコミットをプッシュして、コンフリクト対応は終了です。

git_0108

対策

コンフリクト対策には、次のようなことが考えられます。
  • 細かくプッシュとプルをする
  • 考えて作業を分ける
  • コミュニケーションをとる

細かくプッシュとプルをする

コンフリクトは自分の環境とリモートリポジトリなどの
別の環境との差が開くことで、発生する可能性が高くなります。
その為、できる限り細かくプッシュとプルをするようにしてください。
プッシュは大きな作業が終了してから行うのではなく、
そのタスクを細かくして、そのタスクが完了したら行うようにします。
プルも可能なら朝一と昼休憩の後で少なくとも二回は行うようにしてください。

考えて作業を分ける

コンフリクトが発生するプロジェクトでよくあるのが、
バージョン管理の性質を考えず、作業振り分けをしていることです。
考えずに作業割り振りや作業をファイルを作成すると
同じファイルを変更する可能性が高まります。

できるだけ作業担当者が同じファイルを重複しないように
作業やファイルを分担してください。
例えばエクセルでは、同じbookで別シートを変更しただけでも
コンフリクト扱いになります。
そのため、一つのbookで数多くの作業を行うのではなく、

ある程度のタスクごとにbookを分けて行った方がコンフリクトのリスクは下がります。
作業を考える際に、複数の人間が変更するファイルがどのくらいあるか
把握しておくことは、後々の作業の助けになります。

コミュニケーションをとる

他の人が変更中のファイルを変更したい場合は、変更中の担当者に修正中の箇所を
尋ねるなどしてコミュニケーションをとってください。
そして、変更しても問題なさそうなら変更を行い、コンフリクトが起こりそうなら
作業を内容や作業時間を相手に伝えて、修正タイミングを打ち合わせしてください。

まとめ


  • コンフリクトは自分の修正と他の修正が重複して更新できないこと
  • 修正は開発側で修正をする
  • プルとプッシュを細かくして修正、更新をためないようする
  • 重複しないように作業を分担する
  • コミュニケーションをとって修正タイミングの打ち合わせをする