Cherry-pickは、指定したコミットの変更を現在のブランチに適用するGitコマンドで、元のブランチの全履歴を移行しません。mergeやrebaseとは異なり、cherry-pickは各コミットを個別に処理します。開発者はハッシュで特定のコミットを選択し、その変更のみを移行します。Gitドキュメント(2026年)によると、cherry-pickは完全なマージが過剰または危険な場合に、リリースブランチ間で修正をピンポイントで移行するのに特に役立ちます。このコマンドは新しいハッシュを持つ新しいコミットを作成しますが、元のメッセージと作成者は保持します。
重要ポイント
Cherry-pickは、既存のコミットから変更を取得し、現在のブランチに新しいコミットとして適用するgit cherry-pickコマンドです。元のコミットは自身のブランチに残り、ターゲットブランチに変更のコピーが作成されます。このコマンドは、ブランチ全体を移動せずに特定の修正を移行する必要がある場合に便利です。
構文:git cherry-pick <commit-hash>。Gitは指定したコミットとその親との差分(diff)を分析し、その差分を現在のブランチに適用します。複数のファイルが変更された場合、それらはすべて一緒に移行されます。範囲指定も可能です:git cherry-pick A..B — AからBまでの全コミット(Aを除く)。
フラグで機能を拡張:-n(--no-commit)はコミットを作成せずにワーキングディレクトリとインデックスに変更を適用します — 複数のコミットの変更を1つにまとめる場合に便利です。-xフラグはコミットメッセージに行(cherry picked from commit ...)を追加し、履歴内の変更の出所を追跡しやすくします。
# ハッシュで単一コミットをチェリーピック
git cherry-pick a1b2c3d
# 複数コミットをチェリーピック(順次)
git cherry-pick a1b2c3d e4f5g6h i6j7k8l
# 自動コミットなしでチェリーピック
git cherry-pick -n a1b2c3d
# -xフラグは元のコミットへの参照を追加
git cherry-pick -x a1b2c3d
主なシナリオはリリースブランチ間の修正の移行です。想像してください:developで重大なバグが見つかり修正されました。リリースブランチrelease/v2.1は既に分離されており、このバグも含まれています。develop全体をreleaseにマージすると多くの未完了コードが混入しますが、単一の修正コミットにcherry-pickを適用するのは安全で正確な解決策です。
2つ目のシナリオは変更の元に戻して後で復元する場合です。コミットがgit revertで元に戻され、後でその取り消しが誤りだったことが判明した場合 — 元に戻されたコミットにcherry-pickを適用すると変更が復元されます。これはrevertを取り消すよりも正確で、繰り返し競合が発生しません。
3つ目のシナリオは統合テストのために異なるフィーチャーブランチからのコミットを結合する場合です。複数の未完了ブランチ(未完成コードを含む)をマージする代わりに、各ブランチから準備のできたコミットのみを選択して連携テストを行うことができます。
Cherry-pickは、ブランチ全体ではなく個別のコミットレベルで動作する点でrebaseやmergeと異なります。rebaseがブランチの全コミットを移行し、mergeが2つのブランチを結合するのに対し、cherry-pickは必要なコミットのみを選択します。これにより、より精密なツールとなりますが、より手動での操作が必要です。
もう1つの違いは作成者情報です。Cherry-pick中、Gitはデフォルトで元のコミットの作成者を保持しますが、committerは現在のユーザーになります。コミットメッセージは-xフラグで出所を追跡できます。Rebase中は、作成者とcommitterの両方が新しいハッシュを持つ現在のユーザーになります。
パフォーマンス:単一のコミットにcherry-pickを適用する方が、多数のコミットがある2つのブランチをマージするより高速です。しかし、数十のコミットを移行する必要がある場合は、一時ブランチを作成してrebaseを実行する方が効率的で、多数のハッシュを指定する必要もありません。
| 操作 | 適用範囲 | 副作用 |
|---|---|---|
| Cherry-pick | 個別コミット | 新しいハッシュ、コードの重複 |
| Rebase | ブランチの全コミット | 履歴の書き換え、新しいハッシュ |
| Merge | ブランチの完全マージ | マージコミット、履歴の保持 |
複数コミットは、ハッシュをスペース区切りで列挙して1つのコマンドで移行できます:git cherry-pick A B C。Gitは指定された順序でコミットを順次適用します。いずれかのコミットが競合を引き起こした場合、cherry-pickは一時停止し、開発者は競合を解決した後、git cherry-pick --continueで続行します。
コミット範囲:git cherry-pick A..B(Aの後からBまでの全コミット、Aを除く)およびgit cherry-pick A^..B(AからBまでの全コミットを含む)。範囲指定は、親子関係なしにブランチから全コミットを移行する場合に便利です — 例えば、古いブランチから新しいブランチに完成した機能を移行する場合などです。
--strategyフラグはGitが変更を適用する方法を決定します。デフォルトではrecursive戦略が使用されますが、競合の片側を自動的に選択するためにoursまたはtheirsを指定できます。--mainlineフラグはマージコミットにcherry-pickを適用する際に使用され、diffを計算する親番号(1または2)を指定します。
# Cherry-pickコミット範囲
git cherry-pick develop~5..develop~2
# マージコミットをチェリーピック(親を指定)
git cherry-pick -m 1 m9n0o1p
# theirs戦略を使用
git cherry-pick --strategy=recursive \
--strategy-option=theirs a1b2c3d
# 競合解決後に続行
git cherry-pick --continue
Cherry-pick時の競合は、移行するコミットの変更がターゲットブランチで変更された同じ行に影響する場合に発生します。Gitは実行を一時停止し、競合するファイルをマークして解決を待機します。ステータスでは、これらのファイルはboth modifiedとして表示されます。
競合解決の手順:競合するファイルを開き、競合マーカー(<<<<<<<、=======、>>>>>>>)を見つけ、内容を編集し、マーカーを削除し、解決したファイルにgit addを実行し、git cherry-pick --continueを実行します。競合が解決できない場合 — git cherry-pick --abortでcherry-pick全体をキャンセルし、ブランチを元の状態に戻します。
よくある問題:コミットに既存の変更と同等の変更が既に含まれている場合。この場合、Gitはcherry-pickを試行すると“nothing to commit”または“empty commit”を報告します。--keep-redundant-commitsと--empty=keepフラグは、シーケンスを維持するために空のコミットを作成するようGitに強制し、--skipはそのようなコミットをスキップできます。
# Cherry-pick中の競合 — 停止
git cherry-pick a1b2c3d
# error: a1b2c3d... コミットメッセージを適用できません
# 競合を解決 → インデックスに追加
git add src/conflicted_file.swift
git cherry-pick --continue
# 空のコミットをスキップ(既に適用済み)
git cherry-pick --skip
# 完全中止
git cherry-pick --abort
第一のルール:移行するコミットが自己完結型であることを常に確認してください。コミットAが移行されないコミットBの変更に依存している場合、Aにcherry-pickを適用するとビルドが壊れる可能性があります。Cherry-pickの前に、git show --stat <hash>でコミットがどのファイルを変更したかを確認すると便利です。
第二のルール:cherry-pick操作を文書化してください。-xフラグを使用して、コミットメッセージに元のコミットへの参照を残します。これにより、後で履歴を分析する際に変更の出所を理解するのに役立ちます。-xがないと、cherry-pickは通常のコミットのように見え、その出所はgit log --graphでのみ特定できます。
第三のルール:大きく分岐したブランチ間のcherry-pickは避けてください。コミットの作成から長い時間が経過し、コードベースが大幅に変更された場合、競合は多数かつ複雑になります。そのような場合は、ターゲットブランチで修正を再実装する方が、多数の競合を解決するより時間がかかりません。
よくある質問
チェリーピックするとは、git cherry-pickを介して指定したコミットの変更を現在のブランチに適用することです。コマンドは同じ変更を持つが新しいハッシュの新しいコミットを作成します。元のコミットはそのブランチで変更されずに残ります。これは特定のコミットのみが必要な場合にブランチ全体をマージする代わりの方法です。
Cherry-pickは、ブランチ全体を移動せずに1つ以上の特定のコミットを移行する必要がある場合に選択されます。Mergeはブランチの完全なマージに使用されます。典型的なcherry-pickのシナリオは、開発ブランチからリリースブランチへのバグ修正の移行で、他の変更がまだ準備できていない場合です。
完了前 — git cherry-pick --abortで操作を完全にキャンセルできます。成功裏に完了した後 — git revert <hash>でcherry-pickの変更を取り消すコミットを作成します。--abortとの違い:revertはコミットを履歴から削除せず、新しい取り消しコミットを作成します。
空のコミットは、変更がターゲットブランチに既に存在する場合に発生します。そのようなコミットをスキップするにはgit cherry-pick --skipを、ハッシュの順序を保持するために空のコミットを作成するにはgit cherry-pick --keep-redundant-commitsを使用します。
Cherry-pickは選択したコミット(1つずつまたはリスト)を現在のブランチに移行します。Rebaseはブランチの全コミットを新しいベースに移動します。Cherry-pickは元のブランチを変更しませんが、rebaseは履歴を書き換えます。Cherry-pickは正確ですが手動操作が必要で、rebaseは自動的ですが公開ブランチでは危険です。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。