1. 概要
バージョン管理システム(VCS)としてgitを使用している間は、任意の分岐戦略に従うことができますが、最終的には、機能ブランチの1つからメインブランチまたはメインブランチへの変更を統合する必要があります。
このチュートリアルでは、あるブランチから別のブランチに変更を統合する2つの異なる方法を見ていきます。
2. Git Rebase
簡単に言うと、git rebase は機能ブランチ全体を取得し、メインブランチの先端に移動します。 元の機能ブランチのコミットごとに新しいコミットを作成します。
リベースの仕組みを理解するために、リポジトリに新しいリポジトリと機能ブランチを作成してみましょう。
git clone <your_repository_here>
git branch testBranch1
git branch testBranch2
testBranch1 機能ブランチに新しいファイルを作成し、変更をコミットしてみましょう。
git add .
git commit -m "<Commit_Message_Here>"
git push --set-upstream origin testBranch1
git log
これらのコマンドを実行すると、以下の出力が得られます。
それでは、このブランチをmainブランチにリベースしてみましょう。
git rebase main
これにより、次のメッセージが表示されます。
main ブランチにはコミットがないため、上記のように変更を期待するべきではありません。
それでは、機能ブランチをメインブランチにマージしましょう。
git checkout main
git merge testBranch1
git push
git log
これらのコマンドは以下を出力します:
メインブランチにマージしている間、機能ブランチからコミットIDに変更はありません。 これは、早送りマージで発生することと似ています。
testBranch1をmainブランチに既にマージしているため、testBranch2にはカットされた場所からのコミットがありません。
testBranch2がどのようにリベースおよびマージされるかを見てみましょう。
testBranch2 機能ブランチに新しいファイルを作成し、変更をコミットしてみましょう。
git checkout testBranch2
git add .
git commit -m "<Commit_Message_Here>"
git push --set-upstream origin testBranch2
git log
そして、これらのコマンドの完了後、次のように表示されます。
次に、このブランチをmainブランチにリベースしてみましょう。
git rebase main
そして、これは前のケースとは異なるメッセージを私たちに与えるはずです:
メインブランチにはいくつかのコミットがあるため、機能ブランチはそれに基づいてリベースされました。 次に、メインブランチのfeatureBranch2をマージしましょう。 リベースの前後でfeatureBranch2のコミットIDが異なることを期待する必要があります:
git checkout main
git merge testBranch2
git push
git log
これらのコマンドは以下を出力します:
コミットIDは予想どおり異なります。また、gitロググラフを見ると、リポジトリに線形の履歴があることがわかります。
git log --graph --oneline
上記のコマンドは、コミット情報を1行で表示するグラフ構造を示しています。
3. Gitマージ
Gitマージは、マージする2つのブランチを取得し、共通のベースコミットを見つけてから、ベースコミットの2つのブランチからコミットシーケンスを再生して、ブランチをマージします。
マージがどのように機能するかを理解するために、新しいリポジトリといくつかの機能ブランチを作成しましょう。
ローカルマシンのリポジトリのクローンを作成し、新しい機能ブランチを作成します。
git clone <your_repository_here>
git branch testBranch1
git branch testBranch2
testBranch1 機能ブランチに新しいファイルを作成し、変更をコミットしてみましょう。
git add .
git commit -m "<Commit_Message_Here>"
git push --set-upstream origin testBranch1
git log
これらのコマンドを実行すると、以下の出力が得られます。
次に、mergeコマンドを使用して、この機能ブランチをmainブランチにマージしましょう。
git checkout main
git merge testBranch1
git push
git log
これらのコマンドは以下を出力します:
最新のコミットIDは前の画像と同じですが、HEADポインターがmainブランチを指していることがわかります。
上記は単純なマージであり、機能ブランチで作業している間、メインブランチに変更はありませんでした。
メインブランチと機能ブランチの両方に変更があり、gitがそれらをどのように処理するかという別のシナリオを見てみましょう。
testBranch2 機能ブランチに新しいファイルを作成し、変更をコミットしてみましょう。
git checkout testBranch2
git add .
git commit -m "<Commit_Message_Here>"
git push --set-upstream origin testBranch2
git log
そして、これらのコマンドの完了後、次のようになります。
次に、mergeコマンドを使用して、この機能ブランチをmainブランチにマージしましょう。
git checkout main
git merge testBranch2
git log
その後、ターミナルでそれを見ることができます:
元のコミットが両方の機能ブランチに存在する間、HEADが現在指している別のマージコミットがあります。 最上位のコミットには、両方のブランチのコミットIDを持つ追加の情報キー「Merge」もあります。
ブランチグラフをチェックして、リポジトリの履歴を確認することもできます。
git log --graph --oneline
上記のコマンドは、コミット情報を1行で表示するグラフ構造を示しています。
4. ユースケース
リポジトリ履歴を線形にする必要がある場合は常に、リベースを実行する必要があります。 ただし、他の共同作業者が既存のコミットに基づいて独自の作業を行う可能性があるため、リポジトリ外のコミットにマージするのではなく、リベースの使用に注意する必要があります。
すでにプッシュされたコミットをパブリックリポジトリにリベースすると、コミットIDが異なり、他の開発者のメインブランチとリベースされたメインブランチが分岐しているとgitに思わせる可能性があります。 これにより、複数の共同作業者がいる場合、マージ/同期が困難になる可能性があります。
5. 結論
この記事では、すべての開発者がgitVCSを使用する際に知っておくべきgitマージとgitリベースの基本的な違いについて説明しました。