【gitをソフト開発で使いこなそう:第7回】マージが上手くいかない!どうすればいい?
前回は、マージが上手くいく場面のみ解説しました。ですが実際には、マージが失敗して実行できないときがあります。
今回はマージが失敗する原因であるコンフリクトについて解説します。
更新履歴
2020年4月18日:git add --allと書くべき所を、git add -allとしていたため修正。
コンフリクトとは?
マージを行って履歴を一つにまとめる際、同じ部分が異なる内容になっていることがあります。
この時マージを行うgitは、どちらの内容を優先すれば良いのか分からないため、マージを行うことが出来ません。(一方の内容を優先させてしまうと、もう一方の内容は失われてしまいます。)
このように、履歴が衝突することをコンフリクトと言います。
コンフリクトが起きる時
コンフリクトが起きてしまう場面を、例を挙げて見ていきます。
ブランチAとブランチB両方に、test.txtというファイルが存在しているとします。
またtest.txtの内容は、次のようになっているとします。
test.txt(ブランチA)
あの人だーれ? と、小さな子供が言った。
test.txt(ブランチB)
あの人だーれ? と、私の子供が言った。
このような時ブランチAとBをマージしようとするとコンフリクトが起きます。
なぜなら、同じファイルの同じ行(test.txtの2行目)が異なる内容になっているからです。
コンフリクトを解消する
コンフリクトを解消するには、どちらの内容を残すか選んであげる必要があります。
先ほど挙げたコンフリクトの例であれば、ブランチAの内容を残すか、ブランチBの内容を残すか決める必要があります。
実際にやってみる
先ほど挙げたコンフリクトを、gitで解消してみましょう。
マージを実行したときに、コンフリクトが発生すると次のようなメッセージが表示されます。
>git merge B Auto-merging test.txt CONFLICT (content): Merge conflict in test.txt Automatic merge failed; fix conflicts and then commit the result.
また、コンフリクトが発生すると、HEADが指しているブランチを表示する欄に下の画像にあるような文字が表示されます。(ブランチ名のとなりにMERGINGと表示されている。)
コンフリクトが発生しているファイル(今回はtest.txt)をメモ帳などで、開くと次のように表示されます。
あの人だーれ? <<<<<<<HEAD と、小さな子供が言った。 ======= と、私の子供が言った。 >>>>>>>B
<<<<<<<HEADから=======の内容は、ブランチAの内容を示しており、>>>>>>>Bから=======の内容はブランチBの内容を表しています。(これらの文字は、git側で勝手に追加されます。)
どちらかの内容を消すことで、どちらの内容を残すか決めることが出来ます。
今回は、Bの内容を採用しましょう。test.txtの内容を次のように書き換えます。
あの人だーれ? と、私の子供が言った。
どちらかの内容を消して、ファイルを上書き保存したらそのファイルをコミットします。
git add --all git commit -m ″merge commit″
これでコンフリクトが解消されました。
先ほどブランチ名のとなりに表示されていた、MERGINGという文字も消えているはずです。
次回予告
gitでは、自分で自由にブランチを作成して運用することが出来ます。もちろんそれでも構いませんが、実はどのようにブランチを運用するか決めてあるブランチモデルというものがいくつか存在します。
次回は、ブランチモデルについて解説していきます。
う-ん、よく分からん!
この記事を読んで、疑問に思うことがあったときは、気軽にコメント欄や私のTwitterから質問してください。(すぐに答えを返せるとは限りませんが。)
参考文献
Pro Git
git,GitHubを使うにあたって必要なコマンドの使い方が詳しく解説されています。この連載を読んで分からないことや詳しく知りたいことがあったときはまずProgitを読んでみるといいでしょう。 git-scm.com