git cherry-pickを完全マスター!特定コミットのみを取り込む方法

みなさんこんにちは! フリーランスプログラマーの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は便利なツールですが、これがあるからといって共同開発がうまくいくとは限りません。チーム内でコミュニケーションをしっかりとって、その上で使っていきたいものですね!

この記事を書いた人

学生時代を含めると、かれこれ10年以上プログラマーとして過ごしています。
様々な言語や環境、プロジェクトに関わってきましたので、より実践的な記事をみなさんにお届きるよう情報発信していきます!

目次