はじめに
チェリーピックでのマージコミット取り込みで、どっちの親を取り込むのだ、、と混乱したので、自分なりに整理してみました。
チェリーピック(cherry-pick)とは
チェリーピック(cherry-pick)とは、Gitの操作のひとつで、特定のコミットだけを別のブランチに取り込むことを意味します。
通常、Gitではブランチをマージすると、ブランチ全体の変更がまとめて取り込まれますが、チェリーピックを使うと、特定のコミットだけを選んで別のブランチに反映させることができます。
基本的な操作
例)feature/new-uiブランチのコミットCの変更だけfeature/loginブランチに取り込みたい。
・feature/new-uiブランチのコミット履歴(A~E)
A -- B -- C -- D -- E
このとき、feature/loginブランチ上で以下のように操作します。
git checkout feature/login
git cherry-pick <CのコミットID>
そうすると、Cの変更だけが feature/loginブランチに取り込まれます。
コミットIDとは
Git における「コミットID」は各コミットを一意に識別するための名前みたいなものです。各コミットには、ハッシュ値(40桁の英数字)が自動的に付けられます。
例)a3c9f56f23edb5cd4d2b86b3f6a3ef1b1eac9abc
長いので、普通は最初の7文字くらいで省略されていることが多いです。
git log
コマンドやGitHub上のコミット一覧などから確認できます。
親が2つ以上ある場合
マージコミット(例:main に feature をマージした時のコミット)を取り込む際は、どちらの親との「差分」を取りたいのかによって、意味が変わってくるため、-m
によって、どちらを取り込むかを選択する必要があります。
親1:main(マージ先)
親2:feature(マージ元)
マージ元
・変更を加えたブランチのこと。
・プルリクエストで「この変更をマージしてください!」と提案する側。
・例えば、新機能を追加した feature/login ブランチなど。
マージ先
・変更を取り込みたいブランチのこと。
・多くの場合は main や develop など、プロジェクトの中心になるブランチです。
・プルリクエストでは「このブランチに対して変更を加えますよ」という意味。
cherry-pickの基本的な考え方
・取り込みたいコミットを選んで(=マージ元)
・現在のブランチ(=マージ先)に、その変更内容だけを反映する。
実際のコマンド
git cherry-pick -m 1 <マージコミットID>
git cherry-pick -m 2 <マージコミットID>
-m 1 の意味
・「親1(=マージ先)を基準にして、マージコミットとの差分を取り出す」ということ。
・マージ先(main)とマージコミットの差分 = マージ元(feature)で加えられた変更。
・つまり「マージ元の変更をcherry-pickする」ということ!
-m 2 の意味
・「親2(=マージ元)を基準にして、マージコミットとの差分を取り出す」ということ。
・マージ元から見た差分 = マージ先で上書きされた変更。
・-m 2は特殊なケースで使うことが多く、通常の「feature → main に入った変更を取り出したい」という目的には -m 1 を基本的には使う。-m 2はあまり使わない。
おわりに
作業ブランチから、mainやdevelopなどの中心ブランチなどへ、マージコミットを取り込む際は、基本的には-m 1を使うようです。