別のブランチの修正を取り込む - Git による版管理環境を構築する

SPECIAL


別のブランチの修正を取り込む

Git では、マージやリベースという機能を使って、別々のブランチを 1 つに結合することができます。

たとえば、次のようなブランチがあったとして、マージ機能で結合する方法について見てみます。

状況としては、"master" ブランチが最終リリースを行った時点です。

そして、次期バージョンの開発のために "improve1" ブランチを作成してそこで制作を行っているところで、リリースに不具合が見つかりました。

その不具合に対応するため、途中で "master" ブランチから新たに "fix1" ブランチを作成して、バグフィックスを行いました。

 

さて、"fix1" ブランチでの不具合修正が完了したとします。

このような場合、修正したプログラムをリリースするために、"master" ブランチから "fix1" ブランチまでに行った修正を、次のようにして "master" ブランチに結合(マージ)します。

git checkout master

git merge fix1

このように、まずは "master" ブランチに移動して、そこから "fix1" までに変更された内容をマージしてあげると、"master" ブランチの内容が "fix1" ブランチと同じ内容にまで進みます。

このとき、"master" ブランチと "fix1" ブランチが同じブランチを指すようになったので、不要になった "fix1" ブランチは次のようにして削除しておきます。

git branch -d "fix1"

これで、重複していたブランチが "master" だけになりました。

こうして、リリース版として "fix1" ブランチで実装した修正が "master" ブランチに完全に取り込まれた感じになります。

 

さて、今度は "improve1" ブランチの制作作業が終了したとします。

これを "master" ブランチへ取り込む場合も、手順としては、先ほどと同じ感じになります。

git checkout master

git merge improve1

このようにすることで、"improve1" ブランチが "master" ブランチから分岐したところ(図で言う "COMMIT C")から "improve1" ブランチの最新の状態までの更新内容が、"master" ブランチに結合されます。

ただ今回は、前にお話したマージと違って 2 つの系統("fix1" での修正と、"improve1" での修正)が含まれるところです。そのため、ブランチの仕上がりの印象も随分と変わってきます。

まず、今回の "master" ブランチには "fix1" の修正も含まれる分、今度は "master" ブランチと "improve1" ブランチとは、同じブランチを指しません。

また、2 系統のブランチが結合されるため、それぞれの系統で同じ個所を別の内容に修正していた場合など、場合によっては修正内容が衝突(コンフリクト)する可能性も出てきます。

衝突が発生すると、当該ファイルには衝突したそれぞれの変更内容が、おおよそ次のような形で記録されます。

<<<<<<<

(チェックアウト中のブランチにあった内容)

=======

(マージしたブランチにあった内容)

>>>>>>>

これらを、ソースコードから判断して適切に修正した上で、それを ステージング してあげることで、衝突を解消することができます。

ちなみに、マージ前かマージ後かのどちらかの内容に一括で戻したい場合、例えば、マージ対象として指定したブランチで編集された内容 (theirs) を捨てて自分が持っている内容 (ours) にしたいときには、次のようにします。

git checkout --ours ファイル名

逆に、マージ対象として指定したブランチの内容をそのまま生かす場合は、上記の "--ours" の代わりに "--theirs" とします。

または、"--ours" の代わりに "HEAD~1" などとして、マージ対象でも今自分が持っているものでもない、別のブランチ(この例では 1 つ前のコミット)の内容に入れ替えることもできます。

 

なお、現在どのファイルがコンフリクトしているかは、ワーキングコピーの状態を確認 すると "unmerged" としてリストアップされてくるので、それで確認することができます。

衝突を全て解消したら、最後に コミット することで、マージの作業は完了します。

 

目次