みなさんこんにちは! フリーランスプログラマーのsatoです。
別ブランチにあげている更新の一部を、急遽取り込みたい! なんてことが、開発中に起こることもあると思います。そんな時、覚えておくと便利なのが「cherry-pickコマンド」です!
非常に便利な機能なので、ここで覚えておきましょう。
- [基本]「git cherry-pick」とは
- [基本]「git cherry-pick」を使おう!
- [応用]よくある疑問・質問
今回は、まずcherry-pickの基本的な使い方を学びましょう。その後で、cherry-pickを使った際、よく発生する問題や疑問について見ていくことにしましょうか。それではよろしくお願いします。
「git cherry-pick」とは
まずはcherry-pickの、よくある使用例を、図で見てみましょうか。例えば以下の画像のように、2本のブランチ(ブランチA・ブランチB)で開発が進んでいたとしましょう。
そんな時、急遽ブランチAへ、ブランチBの一部のコミットのみを取り込む必要が出てきました!
取り込む時によく使われるコマンドはmerge(マージ)コマンドですよね! しかしこの場合mergeコマンドは使えません。なぜなら余計なコミットまで取り込んでしまうからです。
ではどうすればいいのか…。そこで登場するのが「cherry-pick」です!
「cherry-pickならば、特定のコミットのみを指定して、取り込むこと」が出来るんです! どうでしょう? これはなかなか汎用性の高いコマンドだと思えないでしょうか。
「git cherry-pick」を使おう!
では実際使い方を見ていきましょう。cherry-pickには、大きく分けると主に二つの使い方があります。
- シンプルに1コミットのみ取り込む方法
- 複数のコミットをひとまとめにして取り込む方法
今回はその二つを軸にして、cherry-pickの使い方を見ていきましょう。
1コミットだけの場合
1コミットだけ取り込む場合は、非常にシンプルです。
$ git cherry-pick [取り込むコミットID]
このように、取り込みたいコミットを指定するだけです。[取り込むコミット]部分へは、コミットIDを指定することになります。
※コミットIDは「git log」などで調べることができます。詳細がわからない人は「よくある疑問・質問」の項目で説明しているので読んでみてください。
複数コミットの場合
コミットAからコミットBまでの間のコミットを、取り込む場合は以下のコマンドで実現ができます。
$ git cherry-pick [コミットID(A)]..[コミットID(B)]
二つのコミットの間に「..」を入れるわけですね! こうするとこで、A〜B間のコミットといった具合に、一気に指定可能です。
よくある疑問・質問
ここからはcherry-pickを使う上で、よく発生する疑問や質問をまとめました。
コミットIDの調べ方
cherry-pickを使うには、該当コミットのコミットIDを探す必要があります。先ほども話が出ましたが、それには「git logコマンド」が有用です。
実行内容:
$ git log
実行結果例:
commit a6651cfa5d63caee134c7ea07061370ffd0fe3dc Merge: xxxxxxxxxxxxxxxxxx Author: xxxxxxxxxxxxxxxxxxxxxxxxxx Date: xxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxx
例えばこんな風に出てきた時「a6651cfa5d63caee134c7ea07061370ffd0fe3dc」部分がそのコミットIDになるわけですね!
メッセージを変更したい
オプションをつけないcherry-pickでは、元のコミットのメッセージがついてしまいます。メッセージを変更したい場合は「-e」オプションをつけましょう!
$ git cherry-pick -e [取り込むコミットID]
このオプションをつけることで、実行後にメッセージの編集が行えます。
コミットはしない!
取り込みはするけど、コミットはしたくない! そんな時は「-n」オプションをつけましょう。
$ git cherry-pick -n [取り込むコミットID]
これで、処理のみをコミットせず取り込むことができます。
空コミットでエラーが出る
なんの変更もないコミットを空コミットと呼びます。この空コミットは「区切りとして空のコミットを入れておくことで、ソースの管理をしやすくする」といったような使われ方をします。
運用ルールによっては、空コミットを多用するプロジェクトもあるでしょう。そんな空コミットが、cherry-pickの対象となった場合、以下のようなエラーが出てしまいます。
nothing to commit, working tree clean (コミットするものは何もない。)そんな空コミットを、無理やり取り込むのなら「–allow-emptybgit」オプションをつけて実行しましょう。
git cherry-pick --allow-emptybgit [取り込むコミットID]
これで取り込むことが可能です。
すでに取り込み済みのコミットを再度取り込むとき
レアなケースではありますが…すでに取り込み済みのコミットを、再度取り込もうとした時などにエラーが発生することがあります。その場合、無理やりその更新を取り込むなら「–keep-reduntant-commit」オプションをつけて、実行することで実行が可能です。
$ git cherry-pick --keep-reduntant-commit [取り込むコミットID]
(ただし、すでにその処理は取り込まれているわけなので、空コミットとなります。)
コンフリクトが起きた時
cherry-pickを実行した時にコンフリクトが発生する可能性があります。その場合は順次解消していきましょう。また複数のコミットを同時に「cherry-pick」している時は、コンフリクトの解消が完了し、そのコミットを作成し終えたら、以下のコマンドを打ちましょう。
git cherry-pick --continue
この「–continue」オプションをつけることで、コンフリクトで止まっていた、cherry-pickの処理を再開することができます。
マージコミットを「cherry-pick」したい!
基本的にマージコミットをcherry-pickすることはできません。「-m」オプションをつけることで、実行は可能です。
しかし、そこまで来たら普通に別の手段を取るべきだと思いますので、詳細は割愛します。どうしても「別ブランチから一部を取り込まなくてはならない状況」以上の状況になってきた場合、ちゃんとチームで相談をしマージを実行したほうが良いでしょう。
まとめ
今回はcherry-pickについて一通り見てきました。「別ブランチの一部の処理のみとってくることが出来る」という、なかなかに強力なコマンドです。からなず覚えておきましょう。
とはいえ、これを多用するような状況に陥っている場合、gitの運用ルールに問題がある可能性があると思います。gitは便利なツールですが、これがあるからといって共同開発がうまくいくとは限りません。チーム内でコミュニケーションをしっかりとって、その上で使っていきたいものですね!