概要
git cherry-pick
は他のブランチのコミットの一部を今のブランチに取り込む- 1つないし複数のコミットを指定可能
- 結果は自動的にコミットされるが、
-n
オプションでステージングのレベルに留めることができる
英語の”cherry pick”はサクランボ狩りのことで、いいサクランボを選んで摘むことから、次のような使われ方をするようだ。
- 自分の気に入ったものだけを選ぶ
- 選り好みする
- 品物や人材を厳選する
- 目玉商品を探し漁る
- 都合のいいデータ・証拠だけを選んで偽装する
準備
次のような内容のローカルリポジトリーを使う。それぞれのコミットで、対応するファイルが作成される。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
[vagrant@localhost example]$ git log --all --graph * commit 39851204a64b3392dd83f21147fc57ba5267f6fa (HEAD -> main) | Author: taustation <taustation@gmail.com> | Date: Sat Aug 14 10:47:01 2021 +0900 | | main1 | | * commit d23428407b485123afa26306f95ba9a8ba9df742 (topic) | | Author: taustation <taustation@gmail.com> | | Date: Sat Aug 14 10:44:40 2021 +0900 | | | | topic2 | | | * commit 675bca2ec610a3552f44bd83673c32f47a5ab041 |/ Author: taustation <taustation@gmail.com> | Date: Sat Aug 14 10:43:45 2021 +0900 | | topic1 | * commit 8567dd9242b60bdf96ddd7a57f0434f087fe706d (origin/main, origin/HEAD) Author: taustation <88479749+taustation@users.noreply.github.com> Date: Sat Aug 14 10:27:48 2021 +0900 Initial commit |
cherry-pick実行
main
ブランチに、topic
ブランチのtopic1コミットだけを取り込みたいとする。
1 2 3 |
[vagrant@localhost example]$ git branch * main topic |
main
ブランチで、topic1
コミットのチェックサムを指定して取り込む。
git cherry-pic コミット指定
1 2 3 4 5 |
[vagrant@localhost example]$ git cherry-pick 675bca2 [main bcc3563] topic1 Date: Sat Aug 14 10:43:45 2021 +0900 1 file changed, 1 insertion(+) create mode 100644 topic1.txt |
結果は以下の通りで、topic
ブランチのtopic1
コミットがmain
ブランチにマージされている。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
[vagrant@localhost example]$ git log --all --graph * commit bcc356384e895559e2e4eb9b96bf57ee3683c5be (HEAD -> main) | Author: taustation <taustation@gmail.com> | Date: Sat Aug 14 10:43:45 2021 +0900 | | topic1 | * commit 39851204a64b3392dd83f21147fc57ba5267f6fa (origin/main, origin/HEAD) | Author: taustation <taustation@gmail.com> | Date: Sat Aug 14 10:47:01 2021 +0900 | | main1 | | * commit d23428407b485123afa26306f95ba9a8ba9df742 (origin/topic, topic) | | Author: taustation <taustation@gmail.com> | | Date: Sat Aug 14 10:44:40 2021 +0900 | | | | topic2 | | | * commit 675bca2ec610a3552f44bd83673c32f47a5ab041 |/ Author: taustation <taustation@gmail.com> | Date: Sat Aug 14 10:43:45 2021 +0900 | | topic1 | * commit 8567dd9242b60bdf96ddd7a57f0434f087fe706d Author: taustation <88479749+taustation@users.noreply.github.com> Date: Sat Aug 14 10:27:48 2021 +0900 Initial commit |
暫定的なcherry-pick
-nオプション
コミットせずに確認だけしたい場合は-n
オプションを付ける。そうすると、コミットはされずにステージングエリアに上げられた状態で留まる。
1 |
[vagrant@localhost example]$ git cherry-pick -n d234284 |
ワーキングツリーではファイルは作成されている。
1 2 |
[vagrant@localhost example]$ ls README.md main1.txt topic1.txt topic2.txt |
しかしコミットされていないので、ログには反映されていない。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
[vagrant@localhost example]$ git log --all --graph * commit bcc356384e895559e2e4eb9b96bf57ee3683c5be (HEAD -> main) | Author: taustation <taustation@gmail.com> | Date: Sat Aug 14 10:43:45 2021 +0900 | | topic1 | * commit 39851204a64b3392dd83f21147fc57ba5267f6fa (origin/main, origin/HEAD) | Author: taustation <taustation@gmail.com> | Date: Sat Aug 14 10:47:01 2021 +0900 | | main1 | | * commit d23428407b485123afa26306f95ba9a8ba9df742 (origin/topic, topic) | | Author: taustation <taustation@gmail.com> | | Date: Sat Aug 14 10:44:40 2021 +0900 | | | | topic2 | | | * commit 675bca2ec610a3552f44bd83673c32f47a5ab041 |/ Author: taustation <taustation@gmail.com> | Date: Sat Aug 14 10:43:45 2021 +0900 | | topic1 | * commit 8567dd9242b60bdf96ddd7a57f0434f087fe706d Author: taustation <88479749+taustation@users.noreply.github.com> Date: Sat Aug 14 10:27:48 2021 +0900 Initial commit |
ファイルはステージングエリアにあり、コミット前の状態。
1 2 3 4 5 6 7 8 |
[vagrant@localhost example]$ git status On branch main Your branch is ahead of 'origin/main' by 1 commit. (use "git push" to publish your local commits) Changes to be committed: (use "git restore --staged <file>..." to unstage) new file: topic2.txt |
暫定cherry-pickの破棄
暫定的なcherry-pickの内容を破棄したい場合は、addを取り消してファイルを削除する。
まず、git reset HEAD
でadd
を取り消す。
1 2 3 4 5 6 7 8 9 10 11 |
[vagrant@localhost example]$ git reset HEAD [vagrant@localhost example]$ git status On branch main Your branch is ahead of 'origin/main' by 1 commit. (use "git push" to publish your local commits) Untracked files: (use "git add <file>..." to include in what will be committed) topic2.txt nothing added to commit but untracked files present (use "git add" to track) |
そして作成されたファイルを削除。
1 2 3 4 5 6 7 |
[vagrant@localhost example]$ rm topic2.txt [vagrant@localhost example]$ git status On branch main Your branch is ahead of 'origin/main' by 1 commit. (use "git push" to publish your local commits) nothing to commit, working tree clean |
暫定cherry-pickのコミット
-n
オプションによる暫定的なcherry-pickの結果を正式にコミットしたい場合は、git commit
を実行する。
1 2 3 4 5 6 |
[vagrant@localhost example]$ git cherry-pick -n d234284 ..... [vagrant@localhost example]$ git commit -m "topic2 added" [main 78d7fa4] topic2 added 1 file changed, 1 insertion(+) create mode 100644 topic2.txt |
ログで確認。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
[vagrant@localhost example]$ git log --all --graph * commit 78d7fa46d6efba17f47328409025f7f7cd9da371 (HEAD -> main) | Author: taustation <taustation@gmail.com> | Date: Sat Aug 14 11:09:45 2021 +0900 | | topic2 added | * commit bcc356384e895559e2e4eb9b96bf57ee3683c5be | Author: taustation <taustation@gmail.com> | Date: Sat Aug 14 10:43:45 2021 +0900 | | topic1 | * commit 39851204a64b3392dd83f21147fc57ba5267f6fa (origin/main, origin/HEAD) | Author: taustation <taustation@gmail.com> | Date: Sat Aug 14 10:47:01 2021 +0900 | | main1 | | * commit d23428407b485123afa26306f95ba9a8ba9df742 (origin/topic, topic) | | Author: taustation <taustation@gmail.com> | | Date: Sat Aug 14 10:44:40 2021 +0900 | | | | topic2 | | | * commit 675bca2ec610a3552f44bd83673c32f47a5ab041 |/ Author: taustation <taustation@gmail.com> | Date: Sat Aug 14 10:43:45 2021 +0900 | | topic1 | * commit 8567dd9242b60bdf96ddd7a57f0434f087fe706d Author: taustation <88479749+taustation@users.noreply.github.com> Date: Sat Aug 14 10:27:48 2021 +0900 Initial commit |