開発中に一部の機能を先行リリースして欲しいとの要望があり、gitについて調べてみると「cherry-pick」という便利なコマンドがあったので備忘録も含め、纏めたいと思います。
##cherry-pickとは
あるコミットの内容を任意のブランチに取り込むコマンド。
##使い方
#取り込みたいブランチに移動
git checkout <ブランチ名>
#取り込みたいコミット内容のIDを指定
git cherry-pick <コミットID>
#コンクリフトが発生する場合がある
無事に変更内容が取り込めたかと思えばコンクリフトが発生。
「cherry-pick」コマンドを使用した際のコミット履歴は以下の通りとなります。
A―C'(master)
\
B―C(develop)
A:初期(「001.txt」の内容:"a")
コミットID:d5737ed658e4d75dd5b67cb7a26e2b52f7e399aa
B:「001.txt」に"b"を追記
コミットID:8cfe601d9fb9b0420441a41907d580b5909ea3b3
C:「001.txt」に"c"を追記
コミットID:9526e7a62cfa426adcaf0abd164e9cf6410ed47c
C':Cをcherry-pick
コミットID:fe8661427c7f57c06728b3eafcee58efed1f47f1
##コンクリフトが発生した手順
①「master」ブランチには001.txtというファイルがあります。
a
②「master」ブランチを元に「develop」ブランチ作成。
git checkout master
git branch develop
③「develop」ブランチに切り替えて001.txtに"b"を追記。
git checkout develop
a
b
④コミット、プッシュし「develop」ブランチのリモートリポジトリに変更内容を適用。
git add 001.txt
git commit -m "変更内容bを追記"
git push origin develop
⑤さらに001.txtに"c"を追加し、上記と同様にコミット、プッシュ。
a
b
c
git add 001.txt
git commit -m "変更内容cを追記"
git push origin develop
⑥「master」ブランチにCの内容を取り込みたいので「master」ブランチに切り替え「cherry-pick」を行う。
git checkout master
git cherry-pick 9526e7a62cfa426adcaf0abd164e9cf6410ed47c
##コンクリフトが発生した理由
「cherry-pick」はあるコミットの変更内容を取り込むコマンドの為、上記の様にCの変更履歴がBに依存する関係の場合はコンクリフトが発生する。
(ここが「merge」コマンドとは違う点。「merge」は変更履歴を含め取り込む。詳しくは「3wayマージ」で調べてみると分かると思います。)
#おまけ
複数のファイルでコンクリフトが発生した時に便利なコマンド。
git checkout --ours <ファイル名>
⇒マージ元(チェックアウトしているブランチ側)
git checkout --theirs <ファイル名>
⇒マージ先
半角スペースを空けることで複数のファイルを指定可能。