对于多分支的代码库,将代码从一个分支转移到另一个分支是常见需求。一种情况是,你需要另一个分支的所有代码变动,那么就采用合并(git merge 或 git rebase),另一种情况是,你只需要部分代码变动(某几个提交),这时可以采用(git cherry-pick) 。
所以 cherry-pick 是 摘取特定 commit 到 自己的分支上 (樱桃采摘)。
1. 使用
1 | # 应用单个提交 |
1.1 现象
上面命令就会将指定的提交commitHash,应用于当前分支。这会在当前分支产生一个新的提交,当然它们的哈希值会不一样。
- A分支log (add 1 和 add 2)
1 | * cf976d8 - (HEAD -> master, origin/master, origin/HEAD) add 2 (2 minutes ago) <liuwei> |
- B分支操作 (add 1)
1 | git cherry-pick 07444e6 |
- 然后再看B分支log: (选中了特定的 commit 到我的分支)
1 | * d38ece4 - (HEAD -> cherry) add 1 (11 seconds ago) <liuwei> |
1.2 其他选项
1 | # 编辑提交信息 |
1.3 代码冲突
1 | # 1. 执行 cherry-pick(可能出现冲突) |
2. 停止使用cherry-pick
cherry-pick 可能产生比冲突更严重的问题:该有冲突却没有冲突。

如上图,apple
代表这个功能是上线状态,berry
代表这个功能是下线状态。
然后我们发现了一些 bug,需要将该功能紧急下线,我们:
- 在 feature 分支上下线该功能(F2):
apple -> berry
- 然后将该操作 cherry-pick 到 master(M2),现在 master 上该功能也下线了
- 然后我们在 feature 分支上进行了 bug 修复,最终解决了 bug,我们在 feature 分支上将该功能上线(F3):
berry -> apple
- 然后我们决定将 featuter 的 bug 修复 merge 到 master
- merge 顺利完成,没有冲突。但是:这行代码仍然是
berry
,下线状态
原因分析:
M3(berry
) 和 F3(apple
) 的最近公共祖先是 A(apple
),因此 git 认为 feature 分支并未修改 apple
的值,master 分支的berry
是最新的修改。
结果合并后 master 分支上这行代码还是 berry
,我们的功能在 master 上还是下线状态。
2.1 经验
1 | # ❌ 不要在公共分支直接 cherry-pick |
2.2 替代方案
- 交互式 Rebase (推荐)
- Format-patch + Apply