很神奇的功能。
簡述
假設這是目前的紀錄:

我現在位於 master 上,然後有 dog 和 cat 這兩個分支。現在我想要把 cat 的內容合併到 master,可是我只想要其中幾個 commit,不想要全部都併進去。
例如我只想要 add cat1 這筆紀錄的話,可以下這段指令:
1 | git cherry-pick 1006eb2 |
這樣 master 就只會多出 add cat1 的紀錄:

不要幫我 commit
有時候你可能想額外加一些東西,所以不希望一下完指令後就直接 commit 出去,這時候可以加上 --no-commit:
1 | git cherry-pick 1006eb2 --no-commit |
這樣子資料就會被放到「暫存區(Stage Area)」,等到全部修改完成後再自己 commit 就行囉。

對 cherry-pick 的誤解
我剛開始學這個指令的時後發現我對它背後的含義有一點誤解,所以特別寫這一段來解釋一下。
先回憶一下剛剛的範例:

在前面的示範中我們是從 cat 中取出 add cat1 的記錄到 master 中,不過如果現在是取出 add cat3 呢?
1 | git cherry-pick 63eeaa5 |
出來的結果就會變這樣子:

看起來沒什麼問題啊?怎麼了嗎?
單從歷史紀錄來看的話確實是沒有什麼問題,但其實 cherry-pick 並不是幫你把 add cat3 給抓出來,而是把 add cat3 給合併。
這樣子說可能聽不懂,所以我們來看一下 add cat3 修改了什麼:

add cat3 只有新一行 Cat3 而已,接著來看一下併完後的 master:

注意到了嗎?最後的內容並不是只有 add cat3 當下所做的改變,而是這個 commit 當下的所有檔案內容,換句話說就是整個合併進來。
所以這就跟我原本想的不太一樣,我以為它只會把「修改的內容」給抓出來而已,但實際上的意思是:
選擇我想要 merge 的位置,並且留下這個位置的 commit 訊息。
我舉幾個例子(這邊為了方便閱讀就不寫 hash 值了):
1 | git cherry-pick 'add cat1' |
意思是「把 add cat1 合併到 master,但只留下 add cat1 的提交紀錄」
1 | git cherry-pick 'add cat2' |
意思是「把 add cat2 合併到 master,但只留下 add cat2 的提交紀錄」
1 | git cherry-pick 'add cat3' |
意思是「把 add cat3 合併到 master,但只留下 add cat3 的提交紀錄」
你可以把上面這幾個範例想成這樣:
1 | git merge 'add cat1' // 合併,但只保留 add cat1 的 commit 紀錄 |
總之你一定要記得:
- cherry-pick 只是用另一種方式來做 merge
- cherry-pick 只是用另一種方式來做 merge
- cherry-pick 只是用另一種方式來做 merge
不管你選擇的位置是哪裡,只要想成你是在做 merge 就好了,跟那個 commit 修改的內容一點關係也沒有。
那什麼時候該用 cherry-pick?
如果有聽懂剛剛的解釋,就能理解 cherry-pick 比較像是「可以自由選擇 commit 紀錄的 merge」,而不是把你想要的修改內容抽出來,所以比較正確的用法大概會是像這樣,一樣是剛剛的例子:

1 | git cherry-pick 63eeaa5 -x |
這邊把 add cat3 合併進來並加上 -x,-x 是用來讓 Git 自動幫我們產生「標準訊息」。
附註:因為 cherry-pick 併完後不會額外產生新的 commit,所以不仔細看的話可能不會知道這份紀錄是併過來的,所以才建議在 commit 內容中加上額外的訊息。

最後完成的結果就會像這樣:

就跟剛剛說的一樣,這裡實際上是幫你合併所有在 cat 中的所有修改,但只有保留 add cat3 的 commit 紀錄。順道一提這段 commit 訊息應該要修改成 add cat1 ~ 3 才比較符合這個 commit 實際上做的事情,但這邊只是為了示範所以就沒特別做了。
總之用 cherry-pick 其實只是令外一種合併方式而已,它可以讓你很輕鬆的拿掉不必要的 commit 紀錄。
如果要用 merge 來產出相同的結果,步驟就會變比較麻煩:
1 | git merge 63eeaa5 |

1 | git reset HEAD~3 // 取消最後 3 筆 commit 紀錄(但保留檔案) |

1 | git commit -am 'add cat3' // 加入暫存區並提交 |

所以兩種方法其實都行,端看你喜歡哪一種而已。