【Git】git cherry-pickの使い方|欲しいコミットを指定してとってくる方法を、実例で分かりやすく解説(初心者向け)

git-prograshi(プロぐらし)-kv git/github
記事内に広告が含まれていることがあります。

Gitにはgit cherry-pickというコマンドがあります。英語のcherry pickとは自分の気に入ったものだけをつまみ食いするという意味です。

つまり、欲しいコミットだけとってくる、自分にとって都合のいい便利コマンドです。


cherry-pickの使い方

cherry-pickの使い方はとても簡単です。取得するコミットは1つだけ、または連続した複数のコミットを取得することができます。

自分のブランチで次のコマンドを実行します。

コミットを1つだけとってくる

 $ git cherry-pick <欲しいコミット番号>


連続したコミットをとってくる

連続したコミットを取得する場合は、コミット番号の始まりと終わりを指定して..で繋ぎます。

 $ git cherry-pick <欲しいコミット番号(開始)>..<欲しいコミット番号(終了)>


コミット複数のコミットを指定してとってくる

連続していない複数のコミットを取得したい場合は、コミット番号の後ろにスペースを空けて、他のコミット番号を指定します。

 $ git cherry-pick <欲しいコミット番号1> <欲しいコミット番号2> <欲しいコミット番号3>,,,,


注意点

コミット番号は過去の履歴の影響を受けるため、同じコミット番号にはなりません。コードの内容を移植して、新しコミット番号が付与されます。


実例

例として、リモートブランチのarticlesブランチの 15d340c70 というコミットを取得します。

▼欲しいコミット

(articlesブランチにて)
$ git log --oneline
15d340c70 (HEAD, origin/articles) [F]Article list
78f5c9911 [F]migration version


▼現在のローカルブランチのコミットログ

$ git log --oneline
3aebedb32 (HEAD -> test) [F]conflict schema.rb version
6e98e6c92 (origin/test) [F]article_rankings model and job

現在のローカルブランチのコミットの最新は 3aebedb32 です。この上に欲しいコミットを追加します。


cherry-pickの実行

git cherry-pickを実行すると、指定したコミットメッセージが表示されます。

$ git cherry-pick 15d340c70
[test 4a76eb1c6] [F]Article list_articles, html_article ArticleRanking
 Author: xxx yyy <xxx+ouo@gmail.com>
 Date: Fri Nov 19 19:06:29 2021 +0900
 1 file changed, 52 insertions(+), 7 deletions(-)

ログを確認すると指定したコミットが一番上に来ていることが確認できます。

$ git log --oneline
4a76eb1c6 (HEAD -> test) [F]Article list_articles, html_article ArticleRanking
3aebedb32 [F]conflict schema.rb version
6e98e6c92 (origin/test) [F]article_rankings model and job


コミット番号は過去のコミットの影響を受けるので、指定したコミット番号 15d340c70 ではなく、新たに 4a76eb1c6 というコミット番号で追加されます。


cherry-pickのオプション

コミットメッセージを変更する(-e)

デフォルトでは元のコミットのコメントをそのまま持ってくる。
オプションで「-e」を指定することでコメントを変更できる。

git cherry-pick -e <コミット>
 ┗ -e = –edit


コミットはしない(-n)

デフォルトでは元のコミットまでされる。
「-n」オプションを指定することで、コミットせず、インデックス(git add)状態で持ってくることができる。

git cherry-pick -n <コミット>
 ┗ -n = –no-commit


空のメッセージを許可(–allow-empty-message)

デフォルトでは空のメッセージのコミットを持ってこようとするとエラーになる。
「–allow-empty-message」をつけることで、空のまま持ってくることができる。

git cherry-pick --allow-empty-message


処理をキャンセルする(–abort)

cherry-pickをなかったことにしたい場合は「–abort」をつける。

git cherry-pick --abort

おかしなことが起こった場合は一旦–abortで回避できる。


コミットを複数指定するときの原理

以下では参考として、コミットを複数指定する場合の原理についてまとめています。


コミットを個別に複数指定する場合

連続していない複数のコミットを取得したい場合は、コミット番号の後ろにスペースを空けて、他のコミット番号を指定します。

 $ git cherry-pick <欲しいコミット番号1> <欲しいコミット番号2> <欲しいコミット番号3>,,,,

原理

例えば、以下のようにmasterブランチと、分岐したtopicブランチがあるとします。

      A---B---C---D topic
     /
D---E---F---G master

masterブランチにいるときに、topicブランチのコミットAとコミットCを取得したい場合は以下のようになります。

$ git cherry-pick A C ↓↓↓

                        master
D---E---F---G---A'---C' 

A、CではなくA’、C’になるのは、後ろの履歴が変わったことで、コミットのハッシュ値が変わるためです。


連続するコミットを指定する場合

連続したコミットを取得する場合は、コミット番号の始まりと終わりを指定して..で繋ぎます。

 $ git cherry-pick <欲しいコミット番号(開始)>..<欲しいコミット番号(終了)>

原理

例えば、以下のようにmasterブランチと、分岐したtopicブランチがあるとします。

      A---B---C topic
     /
D---E---F---G master

masterブランチにいるときに、topicブランチのコミットAからCをまとめて取得したい場合は以下のようになります。

$ git cherry-pick A..C ↓↓↓

                        master
D---E---F---G---A'---B'---C' 

A、B、CではなくA’、B’、C’になるのは、後ろの履歴が変わったことで、コミットのハッシュ値が変わるためです。


merge, rebase, cherry-pickの違い

他のブランチから新しいコミットを作成する主なコマンドに、merge, rebase, cherry-pickがあります。

ここでは参考としてそれらの原理の違いをまとめています。

merge

メインブランチとトピックブランチ両方のコミットをそのまま保持。

      A---B---C topic
     /         
D---E---F---G master

$ git merge topic ↓↓↓

      A---B---C topic
     /         \
D---E---F---G---H master


rebase

トピックブランチのコミットをコピーしてメインブランチの先端に移動

      A---B---C topic
     /
D---E---F---G master

$ git rebase master ↓↓↓

                        topic
D---E---F---G---A'---B'---C' 
          master 


cherry-pick

欲しいコミットだけをコピーし、メインブランチの先端に移動。

      A---B---C topic
     /
D---E---F---G master

$ git cherry-pick B ↓↓↓


D---E---F---G---B' 
          master 
タイトルとURLをコピーしました