今回は、Gitのcherry-pickコマンドについて解説します。
Gitを使っていると、次のような場面はないでしょうか。
- 別のブランチにある特定のコミットだけを取り込みたい
- 他の変更は取り込まず、一部の修正だけ反映したい
- 間違えて別のブランチで作業してしまった
このような場合に便利なのが、Gitのcherry-pickです。
cherry-pickを使うと、指定したコミットの変更内容を現在のブランチに取り込めます。
この記事ではgit cherry-pickの基本的な使い方から、複数コミットの取り込み、コンフリクトした場合の対処方法、取り消し方法まで解説します。
- Git cherry-pickとは?
- git cherry-pickの基本的な使い方
- 取り込みたいコミットIDを確認する方法
- 別のブランチにあるコミットをcherry-pickする方法
- 複数のコミットをcherry-pickする方法
- 連続した複数コミットをcherry-pickする方法
- git cherry-pickでコンフリクトした場合
- git cherry-pickを中止する方法
- 完了したgit cherry-pickを取り消す方法
- git cherry-pickとgit mergeの違い
- git cherry-pickとgit rebaseの違い
- 間違ったブランチでコミットした場合にも便利
- Git cherry-pickの使い方まとめ
Git cherry-pickとは?
git cherry-pickは、指定したコミットの変更内容を現在のブランチに取り込むコマンドです。
例えば、次のようなブランチがあるとします。
main
A --- B --- C
feature
└--- D --- E
featureブランチにあるコミットDだけをmainブランチに取り込みたい場合、git cherry-pickを使用します。
mainブランチに移動した後にcherry-pickコマンドを実行します。
main
A --- B --- C --- D'
^
cherry-pickで取り込んだコミット
feature
└--- D --- E
そうすると、mainブランチにはDの変更内容を持った新しいコミットD'が作成されます。
cherry-pickは、ブランチ全体ではなく、必要なコミットだけを選んで取り込めることが特徴です。
git cherry-pickの基本的な使い方
基本的な使い方は、次のとおりです。
git cherry-pick コミットID
例えば、featureブランチのabc1234というコミットを現在のブランチに取り込む場合は、次のように実行します。
git cherry-pick abc1234
これで、指定したコミットの変更内容が現在のブランチに反映されます。
git cherry-pickを実行する前に、取り込み先のブランチに移動しておく必要があります。
例えば、mainブランチに取り込む場合は次のようになります。
git switch main
git cherry-pick abc1234
取り込みたいコミットIDを確認する方法
cherry-pickで取り込むには、対象のコミットIDが必要です。
コミット履歴は、git logで確認できます。
git log --oneline
実行すると、次のように表示されます。
abc1234 バグを修正
def5678 ログイン機能を追加
ghi9012 READMEを更新
先頭に表示されているabc1234がコミットIDです。
例えば、「バグを修正」というコミットだけを取り込む場合は、次のように実行します。
git cherry-pick abc1234
このようにすることで、abc1234にコミットされた内容だけを現在のブランチに取り込めます。
別のブランチにあるコミットをcherry-pickする方法
別のブランチのコミットを取り込む場合も、基本的な使い方は同じです。
まず、コミットを取り込む先のブランチに移動します。
git switch main
次に、取り込みたいコミットIDを指定します。
git cherry-pick abc1234
これで、別のブランチにあるabc1234の変更内容をmainブランチに取り込めます。
複数のコミットをcherry-pickする方法
複数のコミットを取り込みたい場合は、コミットIDを複数指定できます。
git cherry-pick abc1234 def5678 ghi9012
この場合、指定したコミットを順番に取り込みます。
abc1234 → def5678 → ghi9012
コミットの順番が重要な場合があるため、基本的には古いコミットから順番に指定するのがおすすめです。
連続した複数コミットをcherry-pickする方法
連続した複数のコミットをまとめて取り込みたい場合は、コミットの範囲を指定できます。
git cherry-pick abc1234^..def5678
例えば、コミット履歴が次のようになっているとします。
A --- B --- C --- D
BからDまでを取り込みたい場合は、次のように指定します。
git cherry-pick B^..D
これで、B、C、Dのコミットが順番に取り込まれます。
git cherry-pickでコンフリクトした場合
cherry-pickを実行すると、変更内容が現在のブランチと競合して、コンフリクトが発生する場合があります。
例えば、次のようなメッセージが表示されます。
CONFLICT (content): Merge conflict in sample.txt
この場合は、まずコンフリクトしているファイルを確認します。
git status
そうすると、下記のようにコンフリクトが発生していることが確認できます。
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: sample.txt
コンフリクトはVSCodeなどで開いて、修正しましょう。
ファイルを修正したら、変更をステージングします。
git add sample.txt
その後、次のコマンドでcherry-pickを続行します。
git cherry-pick --continue
問題なければcherry-pickが完了します。
git cherry-pickを中止する方法
git cherry-pickの途中で「間違えたので取り消したい」と思った場合は、次のコマンドを使用します。
git cherry-pick --abort
git cherry-pick --abortを実行すると、現在進行中のcherry-pickを中止し、cherry-pickを開始する前の状態に戻せます。
例えば、複数のコミットを取り込んでいる途中でコンフリクトが発生した場合でも、
git cherry-pick --abort
を実行することで、cherry-pick全体を中止できます。
cherry-pickの途中かどうかは、次のコマンドで確認できます。
git status
途中の場合は、次のように表示されます。
You are currently cherry-picking commit ...
このように表示されている場合は、git resetではなく、git cherry-pick --abortで取り消すのがおすすめです。
完了したgit cherry-pickを取り消す方法
git cherry-pickが正常に完了した後で、取り込んだコミットを取り消したい場合は、git resetを使用できます。
直前のコミットを取り消す場合は、次のコマンドを実行します。
git reset --hard HEAD^
ただし、git reset --hardを実行すると、作業中の未コミットの変更も削除されるため注意が必要です。
複数のコミットをcherry-pickして、それらをまとめて取り消したい場合は、reflogでcherry-pickする前の状態を確認してから戻す方法もあります。
git reflog
例えば、cherry-pick前のコミットIDがabc1234であれば、次のように戻せます。
git reset --hard abc1234
ただし、すでにリモートリポジトリにプッシュしている場合は、履歴を書き換えるgit resetではなく、git revertを使用する方法も検討しましょう。
git cherry-pickとgit mergeの違い
git cherry-pickとgit mergeは、どちらも別のブランチの変更を取り込むために使用できます。
しかし、取り込む対象が異なります。
| コマンド | 特徴 |
|---|---|
git cherry-pick |
特定のコミットだけを取り込む |
git merge |
ブランチの変更をまとめて取り込む |
例えば、次のような状況を考えてみます。
main
A --- B
feature
└--- C --- D --- E
featureブランチの変更をすべて取り込みたい場合は、mergeが向いています。
git merge feature
一方で、Cのコミットだけを取り込みたい場合は、cherry-pickが向いています。
git cherry-pick CのコミットID
「ブランチ全体を統合する」のではなく、「必要な変更だけを取り込む」のがcherry-pickです。
git cherry-pickとgit rebaseの違い
git rebaseもコミット履歴を扱うコマンドですが、cherry-pickとは用途が異なります。
cherry-pickは、指定したコミットを別の場所にコピーするイメージです。
A --- B --- C
Dを取り込み
A --- B --- C --- D'
一方、rebaseは、ブランチのコミットを別のコミットの上に付け替える操作です。
変更前
main: A --- B
\
feature: C --- D
rebase後
main: A --- B --- C' --- D'
必要なコミットだけを別のブランチに取り込みたい場合は、cherry-pickが適しています。
間違ったブランチでコミットした場合にも便利
cherry-pickは、間違ったブランチでコミットしてしまった場合にも便利です。
例えば、本来はfeatureブランチでコミットするはずが、間違えてmainブランチでコミットしてしまったとします。
まず、正しいブランチに移動します。
git switch feature
次に、間違って作成したコミットを取り込みます。
git cherry-pick abc1234
これで、featureブランチに同じ変更内容を取り込めます。
その後、間違ったブランチ側のコミットを削除することで、正しい状態に戻せます。
Git cherry-pickの使い方まとめ
今回は、Gitのcherry-pickについて解説しました。
git cherry-pickは、別のブランチにある特定のコミットだけを現在のブランチに取り込めるコマンドです。
基本的な使い方は次のとおりです。
git cherry-pick コミットID
コンフリクトした場合は、修正してから次のコマンドを実行します。
git add ファイル名
git cherry-pick --continue
cherry-pickを中止したい場合は、次のコマンドを使用します。
git cherry-pick --abort
git mergeのようにブランチ全体を取り込むのではなく、必要なコミットだけを取り込めるのがcherry-pickの特徴です。
「別ブランチのバグ修正だけを反映したい」「間違ったブランチでコミットしてしまった」といった場面で活用してみてください。
コメント