別のブランチの修正を取り込む - 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" としてリストアップされてくるので、それで確認することができます。
衝突を全て解消したら、最後に コミット することで、マージの作業は完了します。
【目次】