これはなに
Gitで、新しいブランチを作成したあと、もとのブランチに更新が入ったときに、どうすればいいのかのメモ。
前提条件
- Gitの基本的な使い方を知っている
- コマンドラインでGitを操作できる
はじめに
Gitを利用する際、たとえばmain
ブランチから新しいブランチを作成したあと、main
ブランチに更新が入ることはよくある。そのときに、main
ブランチの最新の変更を新しいブランチに取り込みたいことがある。
以下では、もとのブランチがmain
ブランチで、新しいブランチがnew-branch
であると仮定して説明する。ただし、この方法は特段main
ブランチに限らず、どのブランチに対しても適用できる。
対応方法の種類
最新の変更を取り込む方法は大別して2つある。
- 新しいブランチの開始点を、
main
ブランチの最新のコミットへ移動する main
ブランチの最新のコミットを、新しいブランチへ取り込む
基本的に、新しいブランチにまだコミットがない場合は1、すでにコミットがある場合は2の方法を取る。 ただし、新しいブランチにコミットがあっても、まだリモートリポジトリにプッシュしていない場合は、1の方法でも問題ない。
事前の準備:作業状態の保存
変更を取り込む前に、git stash
コマンドで現在の作業状態を保存しておくことをオススメする。これにより、操作中に問題が発生した場合でも、簡単に元の状態に戻せる。
git stash save "作業中の変更を一時保存"
この操作により、現在の変更が一時的に保存され、作業ディレクトリがクリーンな状態になる。 後述する操作で変更の取り込みが完了した後、保存した変更は次の操作で復元できる。
git stash pop
pop
オプションを指定することで、最後に保存した変更を復元できる。
手順
新しいブランチの開始点を移動する
この方法は、以下の場合に使える。この方法はコミット履歴を変更してしまうため、リモートリポジトリへプッシュした後は使えない。
- 新しいブランチを作成しただけで、まだ何もコミットしていない場合
- 新しいブランチを作成し、すぐにコミットしているが、まだリモートリポジトリへプッシュしていない場合
まず、新しいブランチに切り替える1。
git switch new-branch
その後、main
ブランチの最新の状態へリベースする。
git rebase main
これにより、新しいブランチの開始点を、main
ブランチの最新のコミットへ移動できる。
コンフリクトが発生した場合は、コンフリクトを解消してからgit rebase --continue
を実行する。
くれぐれも、すでにリモートリポジトリへプッシュしている場合は、rebase
を使ってはならない。なぜなら、rebase
は履歴を書き換える操作だからである。
リモートリポジトリへプッシュした後にrebase
でローカルリポジトリの履歴を書き換えてしまうと、リモートリポジトリとローカルリポジトリとで、コミット履歴の整合性が取れなくなってしまう。
もし、すでに新しいブランチでコミットしていて、リモートリポジトリにプッシュしている場合は、次に述べるmerge
を使う。
新しいブランチに最新のコミットを取り込む
この方法は、以下の場合に使える。この方法はコミット履歴を書き換えないため、リモートリポジトリへプッシュした後でも使える。
- 新しく作成したブランチにすでにコミットがあり、かつ、すでにリモートリポジトリへプッシュしている場合
まず、新しいブランチに切り替える。
git switch new-branch
その後、main
ブランチの最新の状態をマージする。
git merge main
これにより、新しいブランチに、main
ブランチの最新の状態を取り込める。ブランチの開始点は変わらないが、履歴を書き換えずに、新しいブランチの状態をmain
ブランチの最新のコミットへ合わせられる。
マージの際にコミットが作成される点には注意すること。
コンフリクトが発生した場合は、コンフリクトを解消してから通常のコミットを行う。
Appendix | コンフリクトの対処
rebase
やmerge
の際に、同じファイルの同じ部分が両方のブランチで変更されていると、コンフリクトが発生しうる。コンフリクトが発生した場合は、Gitは自動的にマージを停止し、手動での解決を求める。
コンフリクトが発生した場合の一般的な手順は以下のとおりである。本稿では詳細な説明は省略する。
- コンフリクトしたファイルを開く
- コンフリクトのある部分を探す
- 望ましい最終的な内容に編集し、コンフリクトを解決する
- 変更をステージングエリアに追加する
- コンフリクト解決後、
rebase
の場合はgit rebase --continue
を、merge
の場合は通常のコミットを行う
まとめ
新しいブランチを作成した後、もとのブランチに更新が入ったときは、以下の方法で対応できる。
- 新しいブランチにまだコミットがない場合は、
rebase
を利用して、新しいブランチの開始点をmain
ブランチの最新のコミットへ移動する - 新しいブランチにすでにコミットがある場合、とくにリモートリポジトリへプッシュした後の場合は、
merge
を利用して、main
ブランチの最新のコミットを新しいブランチへ取り込む
git switch
はGit 2.23以降で利用可能。それ以前のバージョンではgit checkout
を使う。 ↩︎