git mergeでブランチをマージしよう!いろんな疑問を徹底解説

みなさんこんにちは!

フリーランスプログラマーのsatoです。

gitを使い始めた時、最初につまづく点の一つがmerge(マージ)だと思います。

今回はこのマージについて徹底解説していきますね!

そもそもmergeがなんなのかわからない人も、もっと使いこなしたい人も必見の内容になっていますよ。

コンフリクトの解消手段もまとめていますのでぜひ読んでおいてください!

[基本]mergeとは?
[基本]mergeの使い方
[基本]コンフリクトとは
[応用]mergeには二種類ある!

まずは基本的な使い方を一通り勉強しましょう。

次にmergeの一番の難所である、コンフリクトの解消方法も見ていきましょうか。

続けて「ここを理解していないとうまく扱えない」とも言える、マージの2つの種類について学びましょう。

それでは宜しくお願いします。

mergeとは?

まず早速ですが、マージを一言で説明すると…

「現在のブランチ(HEADの指している場所)へ、他のブランチの更新を取り込む処理」と言えるでしょう。

言葉だけではわからないと思うので図にして見てみましょうか。

現在の開発状況が、以下の図のようだったとしましょう。

開始地点や丸はコミットです。

Aさんの使っているブランチがブランチA

Bさんの使っているブランチがブランチBだったとしましょう。

この状況で、AさんがBさんの更新を取り込みたくなったとしましょう。

そこで登場するのがマージです。

マージを使用すると…

Bさんの更新を取り込み、取り込んだ後のマージコミットが一つ作成されました。

マージコミットには、ちゃんとBさんの更新が含まれています。

つまり自分のブランチへ他のブランチの更新を取り込んだということですね!

mergeの使い方

ここまででマージの概念は理解できたかと思います。

では次にコマンドを使用して、実際にマージを行ってみましょう。

コマンドは非常に簡単です。

取り込みを行いたい場所に居た上で、以下のコマンドを投げましょう。

これだけです。

少し実例を見てみましょう。

例えば先ほどの、AさんがBさんのブランチを取り込む例を見てみましょう。

この画像の状況で、Aさんは最新の「ブランチA」に居たとします。

その状況で以下のコマンドを実行しましょう。

すると…

このように、Bさんの更新を取り込めるわけですね!

コンフリクトとは

マージの基本的な使い方を理解できましたでしょうか?

しかし理解が進んでくると、一つ疑問が湧いてくるとおもます。

「同じ場所を同時に更新してしまったらどうなるんだろう?」

実はこれがあるからマージは難しいのです。

例えば「test.txt」というファイルをgitで管理していたとしましょう。

これを同時に同じ箇所を修正してしまったとします。

この状況でマージを行うと、コンフリクト(衝突)が発生します。

どちらの処理を優先すればいいのか、gitが判別できないからです。

これに関してはユーザーが手動で対処する必要があります。

ではコンフリクトが起きた時にはどう対処すれば良いかの?

それを次に見ていきましょう。

コンフリクトの解消の仕方(手動)

ここでは実例をベースに解消方法を見ていきましょう。

例えばtest.txtの中身が以下のように変更されている状況でマージを行い、コンフリクトが起きた場合を見ていきましょう。

元々:

ブランチAでの変更:

ブランチBでの変更:

コンフリクトの場所を確認

コンフリクトが発生した際、以下のようなエラー文章が流れます。

Auto-merging test.txt
CONFLICT (content): Merge conflict in test.txt
Automatic merge failed; fix conflicts and then commit the result.

これは読めば分かると思いますが「test.txtで衝突が発生しています」というエラー文です。

衝突が起きた場合は、まずエラーをみて場所を判断しましょう!

コンフリクトを解消

そしてそれを解消するためにtext.txtの中身を覗きます。

すると以下のようになっているはずです。

これは、現在いるブランチ(ブランチA)は「BBB」に変更しているけど、ブランチBは「CCC」に変更しているよ!という意味です。

優先したい方だけ残すように修正しましょう。

今回はブランチAのみを残すことにします。

解消し終わったらコミット!

修正が終わったら、必ず変更箇所に対してaddとコミットを行いましょう。

そうすることで、マージコミットが生成されます。

コンフリクトの解消の仕方(片方を破棄する方法)

片方の更新のみ優先したい場合ならば、もっと簡単な方法があります。

checkoutコマンドを利用して、指定したブランチ側のファイルを落とし直す方法です。

ブランチA側(現在いるブランチ)を優先したい:

ブランチB側(取り込むブランチ)を優先したい:

これを使用すると、任意のブランチの内容のみを残すことができます。

またこちらの手段を用いた場合も、addとcommitを最後に行い、マージコミットを作りましょう。

mergeには二種類ある!

ここまでで、マージについて一通り学ぶことができたと思います。

しかしもう一点、重要な要素があるので勉強しておきましょう。

実はマージには2種類のマージがあるんです。

その2種類とは?

・fast-forward(早送りマージとも呼ばれる)
・no-fast-forward

この二つです。

どう違うのかというと、マージコミットが作られないのがfast-forwardのマージ

マージコミットが作られるのが、no-fast-forwardのマージです。

fast-forward

fasta-forwardはマージコミットが作られません。

例えばこのような状況の時は、単純にブランチAに、ブランチBの更新が反映されていないだけです。

そのためマージしても、マージコミットが作られません。

このように、ブランチの位置が最新の位置に移動されるだけです。

no-fast-forward

逆に最初見たように、ブランチAとブランチBで、それぞれ別々の開発が進んでしまっている場合、マージコミットが作られます。

このようにマージコミットが作られるコミットが、no-fast-forwardと呼ばれるコミットです。

–no-ffオプションで必ずマージコミットを作る!

ここまで読んで…

だからなんなんだ?

と初心者の方は思うかもしれませんが、これが結構重要な話なのです。

それは運用ルールによりはしますが、マージコミットが必要ない場合でも、あえてマージコミットを残しておいた方が良いケースも多いからです。

それを実現するために、mergeには–no-ffオプションが存在します。

このオプションをつけると、強制的にマージコミットが作られますので、ぜひ覚えておきましょう!

まとめ

今回はマージについて見てきました。

マージは他人の修正と自分の修正をつなげるために使います。

そこでミスが発生すると、自分にも相手にも損害が発生するため注意しましょう。

ぜひマスターして、スムーズに開発が行えると良いですね!

またコンフリクトを多発させないコツは、定期的なマージです。

長期に渡りマージをしないと、後で大きなコンフリクトが起きて苦労することになります。

ぜひ定期的にマージを心がけましょう!

自分にプログラミングなんて・・・と思っていませんか?

今後10年間で今ある職業の『77%』はなくなると言われています。

人工知能や機械学習を筆頭にVR、AR、ドローンなどの最先端技術の発達はこれからのあなたの働き方に間違いなく影響を与えるでしょう。

将来を見据えてプログラミングができるようになってエンジニアになりたい、自分だけにしかできないクリエイティブな仕事がしたい、、、とお考えの方も少なくないでしょう。

と、同時に「難しそう、、自分にはできないだろう、、、」と諦めている方も多いのではないでしょうか。

弊社マンツーマンレッスンは、お一人お一人に専属のインストラクターがつくので、通常のスクールでは難しい、オリジナルアプリ開発や、フリーランスとしての仕事獲得まで支援しています。

まずは『無料体験レッスン』で弊社コンサルタントと一緒にあなた専用の学習カリキュラムを考えてみてはいかがでしょうか?

詳しくは下の画像をクリックしてください。

cta_mtm2

LINEで送る
Pocket

書いた人

sato

sato

学生時代を含めると、かれこれ10年以上プログラマーとして過ごしています。
様々な言語や環境、プロジェクトに関わってきましたので、より実践的な記事をみなさんにお届きるよう情報発信していきます!

おすすめコンテンツ

あなたにぴったりなプログラミング学習プランを無料で診断!

プログラミング学習の効率を劇的に上げる学習メソッドを解説