当前位置: 首页 > news >正文

Git + Gerrit 第九课:cherry-pick 挑选提交

本节目标

这一节学习 Git 中非常实用的命令:cherry-pick

你要理解这些问题:

什么是 cherry-pick? 什么时候需要 cherry-pick? cherry-pick 和 merge 有什么区别? 如何把某个提交复制到另一个分支? cherry-pick 冲突怎么解决? Gerrit 中如何挑选修复提交到 release 分支?

本节重点命令:

git log --oneline git switch git cherry-pick git cherry-pick --continue git cherry-pick --abort git cherry-pick --skip git status

1. cherry-pick 是什么

cherry-pick的意思是:

从一串提交中,挑选某一个提交,复制到当前分支。

假设有两个分支:

A --- B --- C --- D main \ E --- F release

现在你发现main分支上的D是一个重要 bug 修复。

你不想把整个main都合并到release,只想把D这个提交拿过来。

这时可以在release分支执行:

git cherry-pick D

结果:

A --- B --- C --- D main \ E --- F --- D' release

注意:

D' 是 D 的复制版本。 它的代码改动和 D 类似,但 commit id 不一样。

2. cherry-pick 的直观理解

可以这样理解:

merge 是把一个分支整体合进来。 cherry-pick 是只挑某一个提交拿过来。

例如:

main 分支有 10 个新提交。 release 分支只需要其中 1 个 bug 修复提交。

这时不适合直接 mergemain

因为 merge 会带来很多不需要的修改。

更合适的是:

git cherry-pick 修复提交ID

3. cherry-pick 和 merge 的区别

对比项

merge

cherry-pick

操作对象

一个分支

一个或多个提交

结果

合并整个分支历史

复制指定提交

是否带入其他提交

通常会

不会,只拿指定提交

常见用途

整合功能分支

把修复挑到其他分支

commit id

保留原历史关系

生成新的 commit id

一句话:

merge 是合并分支,cherry-pick 是复制提交。

4. 什么时候使用 cherry-pick

常见场景:

  • master/main上的 bug 修复复制到release分支

  • release上的紧急修复复制回develop

  • 从别人分支挑一个有用提交到自己分支

  • 只想要某个提交,不想合并整个分支

  • 多版本维护时,把同一个修复同步到多个版本分支

典型公司场景:

产品已经发布 v1.0,对应 release/v1.0 分支。 开发主线 main 已经继续开发 v2.0。 现在 main 上修了一个严重 bug。 这个 bug 也影响 v1.0。 你需要把这个 bug 修复提交 cherry-pick 到 release/v1.0。

5. 什么时候不适合 cherry-pick

不适合场景:

  • 你其实需要整个功能分支

  • 提交之间依赖很强,只挑一个会编译失败

  • 想保持完整分支历史

  • 不确定这个提交是否依赖前面的提交

  • 大量提交都要同步,这时 merge 或 rebase 可能更合适

使用前要思考:

这个提交能不能单独工作? 它有没有依赖其他提交? 挑过来会不会缺文件、缺接口、缺配置?

6. cherry-pick 基本流程

假设你要把main上的某个提交挑到release/v1.0

第一步,找到提交 ID:

git log --oneline

示例:

def5678 修复登录空指针问题 abc1234 实现用户登录功能

第二步,切到目标分支:

git switch release/v1.0

第三步,执行 cherry-pick:

git cherry-pick def5678

第四步,检查历史:

git log --oneline

你会看到当前分支多了一个新提交。

7. cherry-pick 会生成新的 commit id

假设原提交是:

def5678 修复登录空指针问题

你在release/v1.0上执行:

git cherry-pick def5678

新提交可能变成:

9999999 修复登录空指针问题

标题一样,代码改动类似,但 commit id 不一样。

原因是:

新提交的父提交不同,所以 commit id 一定不同。

这很正常。

8. cherry-pick 多个提交

你可以一次挑多个提交:

git cherry-pick abc1234 def5678

Git 会按顺序应用这些提交。

也可以挑一个连续范围。

例如:

git cherry-pick A^..C

意思是:

从 A 到 C,包括 A 和 C。

新手阶段建议先一个一个挑:

git cherry-pick 提交ID

这样更容易定位问题。

9. cherry-pick 不自动提交

默认情况下:

git cherry-pick 提交ID

会应用修改并自动创建提交。

如果你想只应用修改,不自动提交,可以使用:

git cherry-pick -n 提交ID

或者:

git cherry-pick --no-commit 提交ID

作用是:

把指定提交的修改放到当前工作区和暂存区,但不自动 commit。

适合场景:

你想挑多个提交后合成一个提交。 你想先检查或调整代码再提交。

10. cherry-pick 可能冲突

如果目标分支和原提交改到了同一个位置,就可能冲突。

例如:

git cherry-pick def5678

可能看到:

CONFLICT (content): Merge conflict in config.txt error: could not apply def5678... 修复登录空指针问题

意思是:

Git 在复制这个提交时遇到了冲突。 你需要手动解决。

11. cherry-pick 冲突解决流程

冲突后先看状态:

git status

打开冲突文件,处理冲突标记:

<<<<<<< HEAD 当前分支内容 ======= 被 cherry-pick 的提交内容 >>>>>>> def5678

整理成最终正确内容后:

git add 冲突文件 git cherry-pick --continue

注意:

cherry-pick 冲突解决后,用 git cherry-pick --continue。 不是直接 git commit。

12. 放弃 cherry-pick

如果你发现挑错了提交,或者冲突太复杂,可以放弃:

git cherry-pick --abort

作用是:

取消当前 cherry-pick,回到 cherry-pick 前的状态。

这和前面学过的:

git merge --abort git rebase --abort git revert --abort

思想类似。

13. 跳过当前提交

如果一次 cherry-pick 多个提交,中途某个提交不想要了,可以:

git cherry-pick --skip

作用是:

跳过当前这个提交,继续后面的提交。

新手不要随便使用--skip

因为它可能导致:

后面的提交缺少依赖。 最终代码不完整。

14. Gerrit 中的 cherry-pick 场景

Gerrit 中常见场景:

一个 bug 修复已经合入 master。 现在 release 分支也需要这个修复。

流程通常是:

git fetch origin git switch release/v1.0 git cherry-pick 修复提交ID git push origin HEAD:refs/for/release/v1.0

这样 Gerrit 会在release/v1.0目标分支上创建一个新的 Change。

注意:

这通常是一个新的 Change。 因为目标分支不同,commit id 也不同。

15. Gerrit 中 Change-Id 的注意点

如果 cherry-pick 的提交来自 Gerrit,它的 commit message 里可能已经有:

Change-Id: Iabc1234567890abcdef1234567890abcdef1234

当你 cherry-pick 到另一个目标分支时,很多 Gerrit 项目允许同一个 Change-Id 出现在不同目标分支上。

但不同公司规范可能不同。

有些团队希望:

同一个修复在不同分支上保留同一个 Change-Id,方便追踪。

也有团队希望:

不同目标分支生成不同 Change。

实际工作中要遵守项目规范。

新手先记住:

不要随便删除或修改 Change-Id。 如果 Gerrit 提示 Change-Id 问题,再按团队规范处理。

16. cherry-pick 后如何检查

执行 cherry-pick 后,不要马上推送。

建议检查:

git status git log --oneline -5 git show --stat HEAD

如果想看最新提交具体内容:

git show HEAD

重点确认:

是不是挑了正确的提交? 有没有引入不该有的文件? 代码是否能在当前分支独立工作? 提交信息是否符合规范? Change-Id 是否符合 Gerrit 要求?

17. cherry-pick 和 amend 的配合

有时 cherry-pick 后,你需要稍微调整代码才能适配目标分支。

例如:

master 上方法叫 ValidateUser release 分支旧代码里方法叫 CheckUser

你 cherry-pick 后修改适配代码。

然后可以:

git add . git commit --amend --no-edit

这样最终还是一个清晰的提交。

再推送到 Gerrit:

git push origin HEAD:refs/for/release/v1.0

18. 实战练习一:基础 cherry-pick

创建练习仓库:

mkdir git-cherry-pick-demo cd git-cherry-pick-demo git init

创建基础提交:

echo "base" > readme.txt git add readme.txt git commit -m "添加基础文件"

创建 release 分支:

git switch -c release/v1.0 echo "release version" >> readme.txt git add readme.txt git commit -m "添加 release 版本说明"

切回主分支:

git switch main

如果主分支叫master

git switch master

在主分支创建 bug 修复提交:

echo "bug fix" > fix.txt git add fix.txt git commit -m "修复示例 bug"

查看提交 ID:

git log --oneline

假设最新提交是:

def5678 修复示例 bug

切到 release 分支:

git switch release/v1.0

挑选这个提交:

git cherry-pick def5678

查看历史:

git log --oneline --graph --all

19. 实战练习二:cherry-pick 冲突

创建练习仓库:

mkdir git-cherry-pick-conflict-demo cd git-cherry-pick-conflict-demo git init

创建基础文件:

echo "version: base" > config.txt git add config.txt git commit -m "添加基础配置"

创建 release 分支:

git switch -c release/v1.0 echo "version: release" > config.txt git add config.txt git commit -m "修改 release 配置"

切回主分支:

git switch main

如果主分支叫master

git switch master

主分支也修改同一行:

echo "version: main fix" > config.txt git add config.txt git commit -m "修复主分支配置"

记录最新提交 ID:

git log --oneline

切回 release:

git switch release/v1.0

执行 cherry-pick:

git cherry-pick 提交ID

这时应该会出现冲突。

20. 实战练习三:解决 cherry-pick 冲突

查看状态:

git status

打开config.txt,你可能看到:

<<<<<<< HEAD version: release ======= version: main fix >>>>>>> 修复主分支配置

改成最终内容:

version: release with main fix

然后:

git add config.txt git cherry-pick --continue

查看历史:

git log --oneline --graph --all

21. 实战练习四:不自动提交

假设你只想应用某个提交的修改,但暂时不提交:

git cherry-pick -n 提交ID

查看状态:

git status git diff --cached

你可以继续调整代码。

调整完成后再提交:

git add . git commit -m "挑选并适配某个修复"

22. 常见错误

错误一:挑错分支

执行 cherry-pick 前先确认当前分支:

git branch git status

你必须在目标分支上执行cherry-pick

错误二:不检查提交依赖

有些提交依赖前面的提交。

只挑一个可能导致:

编译失败 方法不存在 配置缺失 测试失败

挑选前要看:

git show 提交ID

错误三:冲突后直接 git commit

cherry-pick 冲突解决后应该:

git cherry-pick --continue

不是直接:

git commit

错误四:以为 commit id 会一样

cherry-pick 后 commit id 通常会变化。

这是正常的。

错误五:随便修改 Change-Id

Gerrit 项目中不要随便删改Change-Id

如果推送失败或生成了不符合预期的 Change,先确认团队规范。

23. 本节必须记住的命令

git cherry-pick 提交ID git cherry-pick -n 提交ID git cherry-pick --continue git cherry-pick --abort git cherry-pick --skip git show 提交ID git log --oneline

对应含义:

git cherry-pick 提交ID 把指定提交复制到当前分支 git cherry-pick -n 提交ID 只应用修改,不自动提交 git cherry-pick --continue 解决冲突后继续 git cherry-pick --abort 放弃当前 cherry-pick git cherry-pick --skip 跳过当前提交 git show 提交ID 查看某个提交内容 git log --oneline 查看提交历史

24. 本节总结

这一节你学习了cherry-pick

  • cherry-pick用来把某个提交复制到当前分支

  • 它适合把 bug 修复同步到 release 分支

  • 它和merge不同,merge是合并分支,cherry-pick是挑选提交

  • cherry-pick 后通常会生成新的 commit id

  • cherry-pick 可能产生冲突

  • 冲突解决后要用git cherry-pick --continue

  • Gerrit 中常用 cherry-pick 把修复提交推到不同目标分支评审

最重要的一句话:

cherry-pick 是复制一个提交,不是合并整个分支。

下一节建议学习:

Git tag 与 release:如何给版本打标签,以及发布版本在 Git/Gerrit 中如何管理。
http://www.jsqmd.com/news/956144/

相关文章:

  • 如何用BilibiliHistoryFetcher找回你的B站回忆:3分钟快速配置指南
  • 工程与工业摄影测量笔记(超长完整版)
  • DTMF双音频远程控制中转台:原理、设计与实战
  • 3分钟掌握rcedit:Windows可执行文件资源编辑的终极指南
  • 本科毕设级模糊人脸修复工具:带预训练模型、测试脚本和完整目录结构
  • AD7705高精度ADC应用指南:从Σ-Δ原理到实战避坑
  • 3分钟学会:怎样用jsPsych创建零代码的浏览器行为实验
  • 从经典到现代:DeepLearnToolbox深度学习工具箱的完整指南 [特殊字符]
  • 【新手实操】OpenClaw2.7.8 Windows 端完整一键安装实操全过程(包含安装包)
  • 别再靠问卷收反馈了!AI原生时代5种无感采集法,实测提升有效反馈量3.8倍
  • 从寻呼到高速下载:5G PDSCH的MCS与TBSize如何随场景‘智能’切换?
  • TensorFlow语音增强与去混响全流程代码包:含噪声模拟、TFRecords构建、ResNet-RCE训练、PESQ评估及波形重建
  • 2026Intl国际化API时区、地域格式化指纹底层原理与系统本地化模块改造全解
  • Umi-OCR终极指南:3个简单技巧让你轻松掌握免费离线文字识别
  • 5G PDCCH的‘心脏’:手把手拆解CORESET里的CCE与REG映射(附图解)
  • 北京汉堡品牌加盟哪家靠谱,无隐形收费透明签约安心投资开店 - 19120507004
  • DDrawCompat完整教程:让Windows 11完美运行DirectX老游戏的终极方案
  • 阳江流量计厂家五大品牌口碑指南——电磁、超声波、雷达、质量流量计怎么选? - 康宝莱智慧水务
  • Logisim-evolution:从虚拟仿真到物理实现的数字逻辑设计革命
  • 海岛海洋可再生能源多能互补发电系统储能装置的运行与控制策略【附仿真】
  • 鹅厂同事在打饭的时候问我:“Claude Code上下文管理是这么做的?”,打饭阿姨:“满了就压缩,留下重要的,去除噪音,我天天听他们说”
  • 硬件工程师的九大基础必修课:从时钟电源到量产调试的实战指南
  • Standalone Migrations测试策略:如何确保迁移代码的可靠性
  • PyVista三维可视化:从零开始掌握科学数据3D展示的7个关键步骤
  • [智能体-274]:OneHot(单词稀疏向量)→ BoW(文本稀疏向量)→ Word2Vec(单词稠密向量)→ BGE(文本稠密向量)
  • 2026年6月成都龙泉驿德系豪车专修选择指南:益科达口碑、技术、性价比全解析 - 十大排行榜推荐
  • STM32温度控制系统实战指南:从零搭建高精度PID温控方案
  • 终极指南:如何用本地工具永久保存微信聊天记录,打造个人数字记忆库
  • 2026年锦州本地人常去的 5 家黄金回收白银回收铂金回收实体店实地测评汇总 - 诚金汇钻回收公司
  • NetToolsPro V1.2.0 发版