Git マージの使用方法
概要: 開発ブランチを現在のブランチにマージするには、git merge dev-branch-name を使用します。マージに関する競合の警告が表示された場合は、「git merge --abort」を使用してマージを取り消すか、影響を受けるファイルを編集してからコミットします。
Git はブランチを使用して開発ストリームを分離し、安定版リリース ブランチが汚染されるのを防ぎます。ブランチの作業をメインストリームに持ち込むことは、ブランチをマージすることを意味します。方法は次のとおりです。
Git のマージとは
Git は、分岐を簡単かつ迅速に行えるように設計されています。他のバージョン管理システムとは対照的に、Git での分岐は些細なことです。特にマルチ開発者プロジェクトでは、ブランチは Git のコア組織ツールの 1 つです。
ブランチは新しい開発作業をサンドボックス化して、他のブランチ、特にメインまたはマスター ブランチのコードに影響を与えずにコードを変更または追加できるようにします。これには通常、コード ベースの安定したバージョンが含まれます。
これらの変更を安定したコード バージョンから分離することは、まったく理にかなっています。しかし遅かれ早かれ、新しいコードはテストされ、レビューされ、マスター ブランチにロールされるようにゴム印が付けられます。その時点で、ブランチを master ブランチにマージする必要があります。
実際、ブランチはサブブランチを持つことができるため、ブランチをマスターブランチではなく他のブランチにマージする可能性があります。ブランチが何であれ、マージは常に 1 つのブランチを取り、ターゲット ブランチにマージすることを覚えておいてください。 master ブランチを別のブランチにマージしたい場合は、それも可能です。
Git のほとんどのアクションと同様に、ローカル リポジトリでマージを実行し、それらをリモート リポジトリにプッシュします。
Git でブランチをマージする準備をする
ローカル Git リポジトリとリモート Git リポジトリを使用する小さな開発プロジェクトがあります。 「master」ブランチから「bugfix14」というブランチを作成し、バグの解決に取り組みました。
その作業は完了し、コードをテストしました。すべてが期待どおりに機能します。これらの変更を master ブランチにロールバックして、修正がソフトウェアの次のリリースの一部になるようにします。
マージを実行する前に、少し準備が必要です。ターゲット ブランチ (この場合は「マスター」ブランチ) とそれにマージするブランチが両方とも最新であることを確認する必要があります。
これを行うには、git status
コマンドを使用します。
git status
- ブランチ bugfix14: これが現在のブランチです。
- ブランチは「origin/bugfix」で最新です: ローカル リポジトリのブランチには、リモート リポジトリのブランチと同じコミット履歴があります。つまり、それらは同一です。
- Nothing to commit コミットされていないステージング エリアの変更はありません。
- 作業ツリー クリーン: 作業ディレクトリにステージングされていない変更はありません。
これらはすべて、ブランチが最新であることを示しており、続行することは明らかです。これらのいずれかが変更の存在を示している場合は、それらをステージングしてコミットし、リモートにプッシュする必要があります。他の誰かがこれらのファイルに取り組んでいた場合、その変更をリモート リポジトリからプルする必要があるかもしれません。
マージ先のブランチをチェックアウトすると、マージ プロセスが簡素化されます。また、最新であることを確認することもできます。 master ブランチを見てみましょう。
git checkout master
git status
「マスター」ブランチが最新であるという同じ確認が得られます。
マージの実行
マージする前のコミットは次のようになります。
「bugfix14」ブランチは「master」ブランチから分岐しました。 「bugfix14」ブランチが作成された後、「master」ブランチへのコミットがありました。 「bugfix14」ブランチへのコミットがいくつかあります。
2 つのブランチが最新であることを確認し、「マスター」ブランチをチェックアウトしました。 「bugfix14」ブランチを「master」ブランチにマージするコマンドを発行できます。
git merge bugfix14
マージが行われます。 「bugfix14」ブランチはまだ存在しますが、そのブランチで行われた変更は「master」ブランチにマージされました。
この場合、merge コマンドは 3 方向のマージ を実行します。ブランチは 2 つしかありませんが、3 つのコミットが関係しています。これらはいずれかのブランチのヘッドであり、マージ アクション自体を表す 3 番目のコミットです。
リモート リポジトリを更新するには、git push コマンドを使用できます。
git push
サイド ブランチをマージしたら削除することを好む人もいます。他の人は、プロジェクトの真の開発履歴の記録としてそれらを保存するように注意します.
ブランチを削除する場合は、git branch
コマンドに -d
(削除) オプションを付けて実行します。
git branch -d bugfix14
リモート リポジトリのブランチを削除するには、次のコマンドを使用します。
git push origin --delete bugfix14
直線的なコミット履歴が得られますが、それは真の履歴ではありません。
Git で早送りマージを実行する
「マスター」ブランチにコミットしていない場合、履歴は次のようになります。また、「マスター」ブランチの最後にアタッチされるように開発ブランチをリベースした場合も、このようになります。
「master」ブランチにはコミットがないため、「bugfix15」ブランチをマージするために Git がしなければならないことは、「master」ヘッド ポインタを「bugfix15」ブランチの最後のコミットにポイントすることだけです。
通常の git merge
コマンドを使用できます。
git merge bugfix15
これにより、この結果が得られます。
これはこれと同じです:
これはこれとまったく同じです:
Git は、可能な限り早送りマージを実行します。 「マスター」ブランチへのコミットが早送りマージが不可能であることを意味する場合、Git は 3 方向マージ を使用します。
早送りマージを強制することはできませんが、結局のところ不可能かもしれませんが、早送りマージを行うか、何もしないかを宣言することはできます。可能であれば早送りマージを使用するように Git に指示するオプションがありますが、それが不可能な場合は 3 者間マージを行わないようにします。オプションは --ff-only
(早送りマージのみ) です。
これにより、「bugfix15」ブランチが「master」ブランチにマージされますが、早送りマージが可能な場合に限ります。
git merge --ff-only bugfix15
不可能な場合、Git は文句を言って終了します。
git merge --ff-only bugfix16
この場合、「マスター」ブランチへのコミットがあったため、早送りマージはできません。
Git でマージの競合を解決する方法
両方のブランチで同じファイルの同じ部分が変更されている場合、ブランチはマージできません。競合する編集を解決するには、人間の介入が必要です。
ここでは、「master」ブランチにマージしたい「bugfix17」という名前のブランチにある「rot.c」というファイルに変更を加えました。ただし、「rot.c」は「master」ブランチでも変更されています。
git merge bugfix17
マージしようとすると、競合があるという警告が表示されます。 Git は競合するファイルを一覧表示し、マージが失敗したことを通知します。 --abort
オプションを使用して完全に取り消すことができます。
git merge --abort
しかし、マージの解決は思ったほど怖くありません。 Git は私たちを助けるためにいくつかの作業を行いました。競合するファイルの 1 つ (この場合は 1 つしかありません) を編集すると、競合するコード セクションが強調表示されます。
各競合は、7 文字未満の文字「<<<<<<<
」と 7 文字より大きい文字「>>>>>>>
」で区切られています。それらの間の 7 つの等号「=======
」。
- 等号の上のコードは、マージ先のブランチのコードです。
- 等号の下のコードは、マージしようとしているブランチのコードです。
7 文字のセットの 1 つを簡単に検索し、ファイル内で競合から競合へと移動できます。コンフリクトごとに、保持する編集セットを選択する必要があります。拒否するコードと、Git が追加した 7 文字の行を編集する必要があります。
コードは「bugfix17」ブランチから保持します。編集後、ファイルは次のようになります。
これでマージを続行できます。ただし、merge
コマンドではなく、commit
コマンドを使用することに注意してください。
通常どおり、ファイルをステージングしてコミットすることにより、変更をコミットします。最終的なコミットを行う前にステータスを確認します。
git add rot.c
git status
git commit -m "Merged bugfix17"
マージが完了しました。これで、これをリモート リポジトリにプッシュできます。
すべては最終的に融合する
最終的にはすべてのブランチをマージする必要があります。これにより、それらの変更が孤立したり忘れられたりすることがなくなります。
ブランチのマージは簡単ですが、多忙で大規模なチームでは競合への対処が複雑になる可能性があります。競合を解決するには、各開発者から、コードの機能と変更の理由を説明するだけの入力が必要になる場合があります。どの編集を保持するかについて情報に基づいた決定を下す前に、それを理解する必要があります。
残念ながら、Git はそれを助けることができません。