Linuxコマンドの基本:Git:競合の解決

 ここまで学んだgit mergeコマンドは、異なるコミット履歴を結合する強力な機能を持っています。しかし、複数人での並行作業や別々のブランチで同一ファイルの同一箇所を変更すると、Gitがどの変更を採用すべきか判断できなくなり、「競合(コンフリクト)」が発生します。ここでは、競合がなぜ起こるのか、競合発生時にどう対応するかについて、わかりやすく説明します。また、各コマンドについての詳細な解説も加え、競合解決までの流れを理解しやすくします。


なぜ競合が起こるのか

 git mergeコマンドは、2つのコミットから派生した変更を1つに結合するコマンドです。たとえば、「ユーザ1用リポジトリ」でファイルに変更を加えてコミットを進め、「ユーザ2用リポジトリ」でも同じファイルを別の方法で修正した後、その変更を「共有リポジトリ」にプッシュしていたとします。

 この状況で「ユーザ1用リポジトリ」がgit fetchgit mergeで「共有リポジトリ」から新しい履歴を取り込もうとすると、Gitは両方の変更を自動的にマージしようと試みます。両方の変更が同じ行を異なる内容に変更していなければ、問題なくマージが完了し、新たなマージコミットが作成されます。

自動マージが成功する場合

 変更箇所がファイルの異なる行や異なる部分であれば、Gitは自動的にそれらを結合し、マージコミットを作成します。この場合、エディタが起動し、マージコミット用のメッセージを書いて終了すれば完了です。

自動マージが失敗する場合(競合発生)

 しかし、同じ行を別々の内容で修正していると、Gitはどちらの変更を採用すべきか判断できず、マージが停止します。その際、以下のようなメッセージが表示されます。

$ git merge origin/master
Auto-merging logview.sh
CONFLICT (content): Merge conflict in findgrep.sh
Automatic merge failed; fix conflicts and then commit the result.

 この状態が「競合(コンフリクト)」と呼ばれます。競合が起きると、git mergeは最後まで処理を行わず中断します。ユーザは手動でファイルの中から競合箇所を修正して、どの変更を採用するか決定する必要があります。


競合の確認と解決に役立つコマンド

コマンド解説使用例
git diff差分を表示します。競合発生時、差分には<<<<<<<>>>>>>>などの記号が表示され、競合箇所がわかります。$ git diff
git status競合が発生しているファイルがあるか確認できます。$ git status
git add <ファイル>競合箇所を修正したファイルをインデックスに登録します。修正後、通常通りgit addを実行。$ git add findgrep.sh
git commit競合解決後、修正をインデックスに登録したらコミットします。これでマージが完了します。$ git commit -m "競合解決"

競合解決の手順

  1. 競合箇所の確認
     git diffコマンドでファイルをチェックすると、競合箇所が<<<<<<<, =======, >>>>>>>といった区切り記号で示されます。これらの記号の間に「手元の変更」と「取り込もうとした変更」が並んでいます。
  2. ファイルを編集して競合を解消
     テキストエディタで該当ファイルを開き、<<<<<<< HEADから=======までが手元の変更、=======から>>>>>>> some-branchまでが取り込もうとした変更です。必要な変更を残し、不要な記号と行を削除します。最終的に1つの正しい内容に整えます。
  3. 修正内容の登録とコミット
     競合箇所の修正が完了したら、git addでファイルをステージし、git commitでコミットします。これで競合が解決され、マージが完了します。

まとめ

  • git mergeは自動で変更を統合しますが、同じ行に対して異なる変更があれば競合が発生します。
  • 競合が発生すると、git diffで差分を確認し、ファイルを手動で編集して競合箇所を解決します。
  • 修正後はgit addgit commitで競合解決を確定させます。
  • 競合を防ぐには、こまめにgit fetchgit pullで他人の変更を取り込み、同じ箇所で衝突しないよう注意するとよいでしょう。

 このように、競合は複数人で開発する際には避けられない状況ですが、手順を理解すれば簡単に対処できます。慣れることで、よりスムーズなチーム開発が可能となるでしょう。