我們在開發中有時會遇到,需要將另一個分支部分修改同步到當前分支。
如下圖,想把 devA 分支中 commit E 和 F,同步到下面綠色的 devB 分支中。
這時候就可以使用 git cherry-pick
來完成這項任務。
(cherry-pick 有篩選、精選的意思)
一、基本用法
轉移單個提交
git cherry-pick <commitHash>
# 切換到 devB 分支
$ git checkout devB
# Cherry pick 操作
$ git cherry-pick <HashE>
解決衝突後,commit 即可
二、轉移多個提交
如果我有一堆連續的 commit 都想同步過去,那麼可以用下面的語法:
下面的命令可以轉移從 E 到 F 的所有 commit。 注意按順序寫:提交 E 必須早於提交 F
git cherry-pick <HashE>..<HashF>
還要注意上面命令是左開右閉的,即不包含 commit_E,如果需要兩邊都包括,用下面的語法:
git cherry-pick <HashE>^..<HashF>
如果是分開的幾個 commit,可以這樣寫:
git cherry-pick <HashE> <HashG>
三、引數
文件中是這樣寫的:
usage: git cherry-pick [<options>] <commit-ish>...
or: git cherry-pick <subcommand>
--quit end revert or cherry-pick sequence
--continue resume revert or cherry-pick sequence
--abort cancel revert or cherry-pick sequence
--skip skip current commit and continue
--cleanup <mode> how to strip spaces and #comments from message
-n, --no-commit don't automatically commit
-e, --edit edit the commit message
-s, --signoff add a Signed-off-by trailer
-m, --mainline <parent-number>
select mainline parent
--rerere-autoupdate update the index with reused conflict resolution if possible
--strategy <strategy>
merge strategy
-X, --strategy-option <option>
option for merge strategy
-S, --gpg-sign[=<key-id>]
GPG sign commit
-x append commit name
--ff allow fast-forward
--allow-empty preserve initially empty commits
--allow-empty-message
allow commits with empty messages
--keep-redundant-commits
keep redundant, empty commits
提幾個會用得到的:
1)-n
如果你想轉移多個 commit 並在新分支中只想有一個 commit,那就可以新增 -n
引數,不自動提交程式碼,都轉移後一次性手動提交。(注意如果有 conflict 情況就不是很好用)(為了分辨是從其他分支轉移過來的,可以新開一個分支同步這些 commit,然後再 merge 到目標分支)
-n, --no-commit don't automatically commit
2)-x
在提交資訊的末尾追加一行(cherry picked from commit ...),方便以後查到這個提交是如何產生的。
-x append commit name
3)不建議同步「合併(merge)節點」,得到的結果應該不是你想要的(有興趣可以自己嘗試)。
四、程式碼衝突
1)--continue
同步程式碼不可避免遇到衝突情況,解決衝突後,將修改的檔案重新加入暫存區 git add .
,然後使用下面命令繼續:
git cherry-pick --continue
2)--abort
處理過程中可能有誤操作,那麼可以放棄合併,回到操作前的樣子。
git cherry-pick --abort
(3)--quit
發生程式碼衝突後,退出 cherry pick,但是不回到操作前的樣子。
git cherry-pick --quit