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

この記事を書いた人

【プロフィール】
DX認定取得事業者に選定されている株式会社SAMURAIのマーケティング・コミュニケーション部が運営。「質の高いIT教育を、すべての人に」をミッションに、IT・プログラミングを学び始めた初学者の方に向け記事を執筆。
累計指導者数4万5,000名以上のプログラミングスクール「侍エンジニア」、累計登録者数1万8,000人以上のオンライン学習サービス「侍テラコヤ」で扱う教材開発のノウハウ、2013年の創業から運営で得た知見に基づき、記事の執筆だけでなく編集・監修も担当しています。
【専門分野】
IT/Web開発/AI・ロボット開発/インフラ開発/ゲーム開発/AI/Webデザイン

目次