Cherry-pick — 它是什么,机制及在 Git 中的应用

作者: IT Sectr 发布日期: 2026-05-10 阅读时间: 10 分钟

Cherry-pick — 是一个 Git 命令,它将一个或多个现有提交中的更改应用到当前分支。与 Merge(转移整个分支)和 Rebase(转移一系列提交)不同,cherry-pick 只选择指定的提交。根据 git-scm.com, 2025,cherry-pick 在发布分支之间转移修复的场景中最受欢迎。

要点

  • Cherry-pick — 在分支之间转移单个提交,无需完全合并
  • 精准转移 — 选择具体的提交,而不是整个分支
  • 新 SHA — 每次 cherry-pick 都会创建一个哈希值已更改的新提交
  • Hotfix 场景 — cherry-pick 便于将修复转移到发布分支
  • 风险 — 频繁使用时可能导致提交重复和上下文丢失

什么是 Cherry-pick?

Cherry-pick — 是一个 Git 命令,它复制指定提交中的更改,并将其作为新提交应用到当前分支。这个名称来源于"摘樱桃"的比喻:开发人员只选择需要的提交,忽略其余的提交。

Merge 不同,cherry-pick 不会创建合并提交,也不需要完全合并分支。与 Rebase 不同,cherry-pick 不会转移一系列提交——只转移指定的提交。这使得 cherry-pick 成为精准转移修复的理想工具。

根据 Atlassian, 2025 的数据,cherry-pick 在 47% 同时处理多个发布分支的团队中使用。Cherry-pick 在移动开发中尤其受欢迎,因为移动开发需要同时支持多个应用版本(LTS 版本),并且需要在它们之间转移修复。

转移机制

执行 cherry-pick 时,Git 计算指定提交与其父提交之间的 diff,然后将此 diff 应用到当前分支。如果更改无冲突地应用——Git 创建一个具有相同消息但新 SHA 的新提交。如果存在冲突——cherry-pick 暂停等待手动解决。

Cherry-pick 如何工作

Cherry-pick 的语法很简单:指定要转移的提交的哈希值。Git 会将更改复制到当前分支作为新提交。支持同时转移多个提交以及整个范围。

bash
# 将一个提交转移到当前分支
git cherry-pick a1b2c3d4

# 转移多个提交
git cherry-pick a1b2c3d4 e5f6g7h8

# 转移提交范围(从 a1b2 到 f9e8,不包括 a1b2)
git cherry-pick a1b2c3d4..f9e8d7c6

执行 cherry-pick 后,当前分支获得一个包含原始更改的新提交。提交消息默认从原始提交复制,但可以使用 -n(不创建提交)或 --edit(编辑消息)标志进行更改。

转移修复的示例

考虑一个典型场景:在 develop 中发现并修复了一个严重错误,该错误也存在于发布分支 release/v2.0 中。只需要转移此修复,而无需将整个 develop 合并到发布分支。

bash
# 在 develop 中找到包含修复的提交哈希
git log --oneline develop
# a1b2c3d fix: null check in payment processing

# 切换到发布分支
git checkout release/v2.0

# 应用修复
git cherry-pick a1b2c3d4

# 如果有冲突——解决并继续
git add src/payment/PaymentProcessor.kt
git cherry-pick --continue

-x 标志在提交消息中添加对原始 SHA 的引用:"(cherry picked from commit a1b2c3d4)"。这有助于追踪提交的来源。建议在所有场景中使用 -x,但临时草稿除外。

处理冲突

发生冲突时,cherry-pick 的行为类似于 merge:Git 停止并标记冲突文件。开发人员解决冲突,执行 git add,然后执行 git cherry-pick --continue。要取消——git cherry-pick --abort。--strategy 标志允许指定合并策略(例如,带选项的 recursive)。

bash
# 解决 cherry-pick 时的冲突
# Git 显示冲突文件
git status

# 手动解决,然后:
git add 允许文件.kt
git cherry-pick --continue

# 或者取消 cherry-pick:
git cherry-pick --abort

何时使用 Cherry-pick

Cherry-pick 在需要在不合并整个分支的情况下精准转移更改的场景中是最优的。让我们看看 cherry-pick 成为最佳选择的五种主要情况。

  • 转移 hotfix — 修复在 develop 中找到,但需要应用到发布分支(release/v2.0)。Cherry-pick 仅转移修复提交,不触及 develop 中未完成的功能
  • 向后移植到旧版本 — 当前版本的修复需要转移到 LTS 版本。Cherry-pick 只选择需要的提交,而不是合并整个当前代码库
  • 取消其他分支中的提交 — 如果提交在错误的分支中完成,cherry-pick 将其转移到正确的分支,原始提交被取消
  • 转移文档 — 应该存在于所有分支中的 README 或配置文件更改,可以通过 cherry-pick 方便地转移
  • 选择性应用 — 从原型分支中只需要取一个成功的提交,而不将整个原型转移到主开发中

对于移动开发,cherry-pick 在支持多个应用版本时至关重要。例如,如果在已在 Google Play 发布的 3.2 版本中发现错误,而 develop 包含 4.0 版本的代码——cherry-pick 允许在不合并所有 breaking changes 的情况下将修复转移到 v3.x 分支。这对于同时支持两个或更多具有不同 API 和依赖关系的主要版本的项目尤其重要。

实践示例:在移动应用中,发现了在 Android 12 上通过 Google Sign-In 授权时的崩溃。修复已纳入 develop 并通过了审查。但当前发布分支 v2.5 已处于 beta 测试阶段。从 develop 到 release/v2.5 的修复提交的 cherry-pick 允许将修复包含在下一个版本中,而无需转移其他尚未准备好发布的更改。

移动项目中使用 cherry-pick 时,重要的是要考虑依赖关系:如果修复影响在发布分支分歧点之后在 develop 中修改的文件,cherry-pick 可能会带来不完整的更改集。在这种情况下,需要检查所有相关更改是否也已转移,否则应用可能无法编译或工作不正确。在将更改推送到公共分支之前,始终在 cherry-pick 后检查构建。

Cherry-pick vs Merge vs Rebase

Git 中集成更改的三个主要工具——merge、rebase 和 cherry-pick——解决不同的任务。选择取决于需要转移多少更改以及历史应该如何呈现。

标准MergeRebaseCherry-pick
范围整个分支一系列提交选定的提交
历史保留分支结构线性线性
合并提交是(除了 ff)
自动化完全链式仅指定
对于公共分支安全危险安全

Merge——当需要完整合并两个分支并保留分支信息时。Rebase——当需要将个人分支更新到具有干净历史的当前状态时。Cherry-pick——当只需要一个或几个选定的提交时。

在实践中,这些工具是组合使用的:功能开发通过定期 rebase 到 develop 进行,然后通过 --no-ff merge 合并,并在需要将修复转移到其他分支时使用 cherry-pick。每个工具在各自的阶段解决各自的任务。

Cherry-pick 的风险和限制

Cherry-pick——是一个有用但如果不正确或过度使用可能带来风险的工具。主要风险与提交重复、上下文丢失以及后续合并中的冲突有关。

  • 提交重复——如果相同提交稍后通过 merge 进入分支,Git 将创建第二个更改相同的提交。这会污染历史并增加 git bisect 的难度
  • 上下文丢失——cherry-pick 转移 diff,但不转移关于父提交和依赖关系的信息。如果 cherry-pick 应用了提交 A 而没有应用 A 依赖的提交 B,可能会产生逻辑错误
  • 合并时的冲突——cherry-pick 后,在完全合并分支时,Git 可能会两次看到相同的更改并创建在普通合并中可以避免的冲突
  • 缺乏联系——没有 -x 标志就无法理解提交是从其他分支转移过来的。在查找更改来源时,开发人员可能花费数小时来确定提交的起源

风险最小化建议:始终使用 -x 标志指定原始 SHA,在提交消息中记录 cherry-pick 的原因,并在上下文允许时尽可能使用 merge 而不是 cherry-pick。如果 cherry-pick 数量过多——考虑重组分支。

Cherry-pick 时的检查自动化

CI 流水线应将 cherry-pick 视为单独的场景。建议设置自动检查:在创建 cherry-pick 提交时,CI 检查修改的文件是否符合预期集合并对受影响的模块运行测试。这降低了在分支之间精准转移更改时回归的风险。

常见问题

Cherry-pick 和 git revert 有什么区别?

Cherry-pick 将更改从一个提交转移到另一个分支。Revert 创建一个新提交,用于撤销同一分支中指定提交的更改。Revert 不会删除历史——它添加反向更改。

可以同时 cherry-pick 多个提交吗?

可以git cherry-pick A B C——按顺序转移提交 A、B 和 C。或者 git cherry-pick A..C——转移从 A 到 C 的所有提交(不包括 A)。转移顺序与命令中的顺序一致。

Cherry-pick 如何处理合并提交?

默认情况下,cherry-pick 不适用于合并提交,因为合并提交有两个父提交。使用 -m 1 标志指定与哪个父提交比较。-m 1 相对于第一个父提交获取 diff。

如果 cherry-pick 创建了错误的提交该怎么办?

取消 cherry-pick 可以通过 git reset --hard HEAD~1 完成,如果这是最后一个提交。如果提交已推送——使用 git revert <SHA> 创建撤销提交。

Cherry-pick 可以将提交从一个分支转移到同一分支吗?

没有意义,但技术上是可行的。如果提交已存在于分支中,Git 将检测到更改已应用并报告:"The previous cherry-pick is now empty, possibly due to conflict resolution."提交不会再次创建。

总结

  • Cherry-pick——在分支之间转移选定的提交而无需完全合并
  • 机制——Git 计算提交的 diff 并将其作为新提交应用到 target
  • Hotfix 场景——主要用例:将修复转移到发布分支
  • -x 标志——必须用于记录已转移提交的原始 SHA
  • 风险——提交重复、上下文丢失、未来合并中的冲突
  • 与 Merge 的区别——cherry-pick 精准,merge 完整合并分支
  • 与 Rebase 的区别——cherry-pick 手动选择提交,rebase 自动处理链

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读