ブランチ

ブランチの統合

作業が完了したトピックブランチは、最終的に統合ブランチに統合されます。 ブランチの統合には、mergeを使う方法と、rebaseを使う方法の2種類があります。どちらを使うかで統合後のブランチの履歴が大きく異なります。

merge

mergeを使用すると、複数の履歴の流れを合流させることができます。

例えば、下の図のようにmasterブランチから分岐するbugfixというブランチがあるとします。

ブランチ

このbugfixブランチをmasterブランチにマージする時、masterブランチの状態が以前から変更されていなければ、非常に簡単にマージを行うことができます。 bugfixブランチの履歴はmasterブランチの履歴をすべて含んでいるため、masterブランチは単純に移動するだけでbugfixブランチの内容を取り込むことができます。なお、このようなマージをfast-forward(早送り)マージと呼びます 。

fast-forwardマージ

しかし、masterブランチの履歴がbugfixブランチを分岐した時より進んでしまっている場合もあります。この場合は両方のmasterブランチでの変更内容とbugfixブランチでの変更内容を一つにまとめる必要があります。

ブランチを分岐した時より進んでしまっている場合

そのため、両方の変更を取り込んだマージコミットが作成されます。masterブランチの先頭はそのコミットに移動します。

両方の変更を取り込んだマージコミット

Note

マージの実行時に、non fast-forwardマージというオプションを指定することで、fast-forwardマージが可能な場合でも新しくマージコミットを作成して合流させることもできます。

non fast-forwardマージ

non fast-forwardを行うと、ブランチがそのまま残るので、そのブランチで行った作業の特定が容易になります。

rebase

mergeの例と同じく、下の図のようにmasterブランチから分岐するbugfixというブランチがあるとします。

ブランチ

これにrebaseを使ってブランチの統合を行った場合には次の図のような履歴になります。では、どのような手順でマージするのかを簡単に説明します。

rebaseを使ってブランチの統合

まず、bugfixブランチをmasterブランチにrebaseすると、bugfixブランチの履歴がmasterブランチの後ろに付け替えられます。そのため、図のように履歴は一本化されます。

この時移動するコミットXとYでは競合が発生する場合があります。その時はそれぞれのコミットで発生した競合箇所を修正していく必要があります。

rebaseを使ってブランチの統合

rebaseしただけだとmasterの先頭の位置はそのままです。そのため、masterブランチからbugfixブランチをマージして、bugfixの先頭まで移動します。

rebaseを使ってブランチの統合

Note

mergeとrebaseは共に履歴を統合しますが、特徴が異なります。

  • merge
    変更内容の履歴はそのまま残るが、履歴が複雑になる。
  • rebase
    履歴は単純になるが、元のコミットから変更内容が変更される。
    そのため、元のコミットを動かない状態にしてしまうことがある。

mergeとrebaseは、チームの運用方針に応じて使い分けます。
例えば、履歴を一本化するように運用をするのであれば

  • トピックブランチに統合ブランチの最新のコードを取り込む場合はrebaseを使う
  • 統合ブランチにトピックブランチを取り込む場合は、まずrebaseしてからmerge

というように使い分けます。