Git cherry-pick 使用小技巧
背景
前段時間我在實現 StarRocks 的一個關于資源限制的特性[1],由于該功能需要基于最新的 3.5 tag 進行開發,所以我需要需要從 3.5 的 tag 里拉出一個分支(3.5-feature)開發完成后再向上游的 main 分支提交 PR。
解決方案
如果直接使用 3.5-feature 分支向 main 提交 PR 會有很多之前的 commit 導致文件修改很多,所以得換一種方式提交這些變更。
stash
解決這個問題的辦法也蠻多的,第一種是使用 git stash。
這個可以先將修改臨時保存,然后再需要的時候再將 stash 里的數據應用到當前分支。
但這樣有幾個問題:
? 開發的過程中沒法提交代碼了,提交之后就沒法保存到 stash 里,沒有提交代碼總會有丟數據的風險。
? 后續需要多次提交時,stash 也不支持,畢竟 stash 之后當前分支的代碼就沒有了。
手動復制
第二種辦法那就是先把代碼提交到 3.5-feature,然后重新基于 main 分支重新拉取一個分支,再手動對比 3.5-feature 的提交記錄進行修改。
這樣的好處是提交記錄比較干凈,但壞處是改動較多的話容易遺漏代碼,并且每次在 3.5-feature 的改動都需要人工同步過來。
cherry-pick
我第一次看到 cherry-pick 的用法還是在 Pulsar 社區里,經常看到有 PR[2] 將某個在 main 分支的特性 cherry-pick 到其他分支。
圖片
或者是一些重要的安全更新也需要在一些維護版本的分支進行修復。
圖片
cherry-pick 的主要作用是將其他分支的特定提交精確合并到當前分支,以便在不合并整個分支的情況下同步修復、hot-fix 或者是復用代碼;
使用流程如下:
git checkout main
git pull origin main
git checkout -b main-feature# 只pick你真正需要的功能相關提交
# 你的核心功能提交1
git cherry-pick abc123
# 你的核心功能提交2
git cherry-pick def456 ...
圖片
這里的 abc123 和 def456 都是提交記錄的 hash 值,可以通過 git log 命令獲取;也可以在 github 的提交記錄頁面復制。
如果碰到沖突先解決,然后執行:
git cherry-pick --continue
git push origin main-feature假設存在兩個分支:
a - b - c - d main
\
e - f - g main-featuregit cherry-pick f現在需要將 main-feature 分支里的 f 提交到 main 分支,cherry-pick 之后會變成這樣:
a - b - c - d - f main
\
e - f - g main-featuref 這個提交就會被追加到頭部。
適用場景
cherry-pick 主要應用與一些小的修復,安全更新、緊急 bug 的處理,如果一個分支上的大部分 commit 都要被 cherry-pick 到另一個分支,不如考慮直接 使用 merge 或者 rebase。
就像這個功能的名稱一樣:摘櫻桃。選擇合適的果子進行摘取,而不是把所有的提交都合并過去。
#Blog #Github #Git
引用鏈接
[1] 資源限制的特性: https://github.com/StarRocks/starrocks/pull/62705
[2] PR: https://github.com/apache/pulsar/pull/24571





























