はじめに
Gitを用いたチーム開発において、「開発中の機能ブランチから、特定のバグ修正コミットだけを先行して本番ブランチ(main)に反映させたい」という場面に遭遇することがあります。
ブランチごとマージしてしまうと、まだリリースできない未完成の機能まで本番に取り込まれてしまいます。
このような時に役立つのが git cherry-pick コマンドです。本記事では、特定のコミットだけを「つまみ食い」して取り込む git cherry-pick の基本的な使い方、コンフリクト時の解決手順、および運用の注意点を解説します。
1. git cherry-pick とは?
git cherry-pick は、他のブランチにある特定のコミット(差分変更)を、現在チェックアウトしているブランチの先端にコピーして適用するコマンドです。
主なユースケース
- バグ修正の先行リリース(Hotfix): 開発中(feature)ブランチで発見・修正したバグを、機能リリースを待たずに
mainブランチに今すぐ適用したい場合。 - 間違ったブランチでのコミット修正: 本来別のブランチでコミットすべきだった内容を、正しいブランチにコピーし、元のブランチから削除(リセット)したい場合。
2. 基本的な実行手順
それでは、実際のコマンド操作の手順を見ていきましょう。
ステップ1: 取り込みたいコミットハッシュを確認する
まず、コミットが含まれている元のブランチに移動するか、ログを表示して、対象のコミットハッシュ(例: a1b2c3d)を確認します。
git log --oneline
ステップ2: 取り込み先のブランチに切り替える
コミットを適用したいブランチ(例: main)へチェックアウトします。
git checkout main
ステップ3: cherry-pickを実行する
確認したコミットハッシュを指定してコマンドを実行します。
git cherry-pick a1b2c3d
これで、a1b2c3d の変更内容が現在のブランチに新しいコミットとしてコピーされます。元のブランチのコミットメッセージも自動的に引き継がれます。
複数のコミットを一度に取り込む場合
スペース区切りで並べるか、範囲指定(..)を行います。
# 複数の個別コミットを指定
git cherry-pick a1b2c3d e5f6g7h
# コミットAからコミットBの範囲(Aは含まれず、Bは含まれる)を指定
git cherry-pick A..B
3. コンフリクト(競合)が発生した場合の対処法
cherry-pickはコミット時点の差分を適用するため、適用先ファイルのコード構造が大きく異なっていると、コンフリクトが発生して処理が一時停止します。
対処の手順
- 競合箇所を修正する:
エディタで競合箇所(
<<<<<<<から>>>>>>>)を手動で編集し、保存します。 - ファイルをステージングに追加する:
git add <修正したファイル名> - cherry-pickを続行する:
以下を実行すると、処理が再開され、コミットが作成されます。
git cherry-pick --continue
途中で中断して元の状態に戻したい場合
競合が複雑すぎてやり直したい場合は、以下のコマンドで安全に適用前の状態に戻せます。
git cherry-pick --abort
4. 運用の注意点とデメリット
git cherry-pick は非常に便利ですが、多用しすぎるとGitのツリー(履歴)が複雑化するため、以下の注意点を意識する必要があります。
- 同一内容の別コミットが生まれる: cherry-pickしたコミットは、元のコミットと「内容は同じ」ですが「ハッシュ値の異なる全く別のコミット」になります。後でブランチ同士を普通にマージする際、同じ変更が重複して適用され、コンフリクトの原因になることがあります。
- コミットメッセージの工夫:
あとで追跡しやすくするため、cherry-pick時に元のコミット情報をメッセージに残しておくオプション(
-x)を付けるのがチーム開発では推奨されます。これを行うと、コミットメッセージにgit cherry-pick -x a1b2c3d(cherry picked from commit a1b2c3d...)という追記が自動でなされます。
まとめ
git cherry-pick は緊急のバグ修正やコミットの間違いをカバーする「レスキューツール」として重宝します。
ただし、基本的な機能開発などの通常マージには極力通常の git merge や git rebase を使い、どうしても一部の変更だけを切り出したい場合の「最終手段」として安全に運用するようにしましょう。
