Git Cherry-pick:核心命令、实践详解

Git Cherry-pick:核心命令、实践详解

一、Cherry-pick

1. 简介

在多分支协作开发中,我们常常只想把某个分支上的单个或若干次提交,合并到另一个分支,而不需要合并整个分支。Git 提供的 cherry-pick 命令,正是为此而生的利器。

掌握 cherry-pick 如同获得代码移植手术刀,合理使用能让你的版本控制更加优雅高效!🎯

2. 核心目的

git cherry-pick 的核心目的:将指定提交(commit)复制到另一个分支,形成一个全新的提交。在多人协作或多分支开发时,难免出现以下场景:

  • 某个修复或新功能在 dev 分支上完成,但紧急想把它合并到 master 分支上单独发布。
  • 不想合并整个分支,只想把分支中"部分有用提交"挑选出来到另一个分支。

此时 cherry-pick 可以轻松解决问题。记住一点:在目标分支上,Cherry-pick 生成的是新的 commit,其哈希值会与原分支不同。

二、基本用法

plain 复制代码
$ git cherry-pick <commitHash>
  • <commitHash> 通常指要复制的提交的哈希值,也可以是分支名(代表分支最新的那次提交)。
  • 执行后,当前分支会产生一个新的提交,内容和被复制的提交相同,但哈希值不同。

1. 基本命令以及用法

操作 命令示例 说明
将单个提交应用到当前分支 git cherry-pick <commitHash> 将 <commitHash> 对应的提交复制到当前分支,产生一个新的提交(新的哈希值)。
将某分支最新提交复制过来 git cherry-pick <branchName> 例如 git cherry-pick feature 表示复制 feature 分支中"最近一次提交"到当前分支。
一次性复制多个提交 git cherry-pick <HashA> <HashB> 将多个提交依次应用到当前分支,生成多个新的提交。
复制一段连续提交 git cherry-pick A...B 复制从 A(不含)到 B(含)的所有提交到当前分支;如果要包含 A,也可用 A^...B。
跨仓库复制提交 1. git remote add target <gitUrl> 2. git fetch target 3. git cherry-pick <commitHash> 先添加远程仓库并 fetch,拿到远程分支的提交后,通过 cherry-pick 复制到本地当前分支。

2. 示例:

假设当前有两个分支:master 和 feature,feature 分支中有一个提交 Hash 为 f。我们想要把 f 提交应用到 master 分支。

  1. 切换到 master 分支:
git 复制代码
git checkout master
  1. 在 master 分支上执行 Cherry-pick:
git 复制代码
git cherry-pick f

这样就把提交 f 整合到了 master 分支上,会生成一个新的哈希。

如果要转移的是 feature 分支最近一次的提交,也可以直接:

git 复制代码
git cherry-pick feature

三、一次性转移多个提交

Cherry-pick 可以一次性转移多个提交,使用方法也很灵活。

1. 显式列出多个 Hash:

plain 复制代码
git cherry-pick <HashA> <HashB>

将 HashA 和 HashB 这两个提交依次应用到当前分支,形成两个新提交。

2. 转移一段连续的提交:

plain 复制代码
git cherry-pick A..B
  • 该命令会转移从 A(不含)到 B(含)这段提交。
  • 注意:A 必须在时间线(提交历史)上早于 B,否则会出错或得到意料外的结果。
  • 如果需要包含 A 本身,也可以使用 A^...B。

使用连续区间的方式,能减少命令行输入,适合你要一次性转移多个连续的提交。

四、常用配置项

Cherry-pick 有一些常用的参数,可以增强在实际项目中的灵活性。

1. -e / --edit

  • 打开外部编辑器,让你编辑提交信息。
  • 用于在复制过来的提交信息里补充备注,或对原先的提交信息做修改。

2. -n / --no-commit

  • 只更新工作区和暂存区,而不自动产生命令对应的新提交。
  • 适用于你想先合并多个提交,然后再一次性手动提交。

3. -x

  • 在提交信息末尾追加一行 (cherry picked from commit <原始Hash>)。
  • 这行信息可帮助追溯该提交的来源,遇到问题能快速定位。

4. -s / --signoff

  • 在提交信息末尾附加操作者的签名(类似 Signed-off-by: <Name> <Email>)。
  • 一般用于审计或标记提交来源的人。

5. -m parent-number / --mainline parent-number

  • 如果原始提交是一个合并节点(拥有多个父提交),默认情况下 Cherry-pick 会失败,因为它不知道应该采用哪个父提交的变动。
  • -m 参数用来指定使用哪个父提交:
git 复制代码
git cherry-pick -m 1 <commitHash>
  • parent-number 从 1 开始计数:
    • 1 号父提交为"接受合并的分支"(the branch being merged into),
    • 2 号父提交为"提供变动的分支"(the branch being merged from)。

6. 配置项总结

参数或配置 命令示例 说明
-e / --edit git cherry-pick -e <commitHash> 打开编辑器修改提交信息,适合想在提交信息里补充/修改说明的情况。
-n / --no-commit git cherry-pick -n <commitHash> 仅更新工作区和暂存区,不自动创建新提交;可将多个提交合并后再手动一次性 git commit。
-x git cherry-pick -x <commitHash> 在提交信息末尾添加 (cherry picked from commit <originalHash>),便于后续追溯该提交来源。
-s / --signoff git cherry-pick -s <commitHash> 在提交信息末尾追加 Signed-off-by 签名,标明是谁进行了 cherry-pick 操作。
-m / --mainline <parent-number> git cherry-pick -m 1 <mergeCommitHash> 如果目标提交是合并提交(有多个父提交),则用 -m 指定采用哪一个父提交; parent-number 从 1 开始计数,一般 1 为被合并分支,2 为提供合并内容的分支。

五、代码冲突处理

当 Cherry-pick 过程中遇到代码冲突,Git 会暂停操作,等待你手动解决冲突并指定后续流程。常见命令有:

1. --continue

  • 先解决完冲突(编辑冲突文件),然后 git add . 把修改添加到暂存区,最后执行:
git 复制代码
git cherry-pick --continue
  • 让 Cherry-pick 继续执行剩余的操作。

2. --abort

  • 放弃这次 Cherry-pick:
plain 复制代码
git cherry-pick --abort
  • 回到 Cherry-pick 操作前的分支状态,仿佛什么都没发生过。

3. --quit

  • 退出 Cherry-pick,但不恢复到操作之前的状态,保留已经合并到工作区和暂存区的修改。
  • 通常很少使用,除非你想手动控制后续所有操作。

4. 冲突处理总结

操作 命令示例 说明
继续 git cherry-pick --continue 先解决冲突并将文件 git add 至暂存区后,再执行本命令继续 Cherry-pick 剩余操作。
放弃 git cherry-pick --abort 放弃这次操作,工作区回到 cherry-pick 前的状态,仿佛未曾进行过 cherry-pick。
退出 git cherry-pick --quit 退出 cherry-pick,不恢复到操作前的状态,已合并到工作区或暂存区的修改会保留。一般少用,除非你想手动处理后续所有事情。

六、跨代码库的 Cherry-pick

Cherry-pick 还能将另一个远程代码库的提交,转移到本地仓库。具体步骤如下:

1. 添加远程仓库

git 复制代码
git remote add target git://gitUrl

2. 抓取远程内容

git 复制代码
git fetch target

3. 查看要 Cherry-pick 的提交哈希

git 复制代码
git log target/master

4. 执行 Cherry-pick

git 复制代码
git cherry-pick <commitHash>

这样就把远程仓库 target 某个分支上的提交复制到你的本地当前分支。

七、Demo

假设想把 dev 分支上某次提交(哈希值为 f99f2b57)移到 master 分支:

1. 切换到 master:

plain 复制代码
git checkout master

2. Cherry-pick:

plain 复制代码
git cherry-pick f99f2b57b7ee72d55a08e699fbeec34cbac96cb8

3. 推送到远程 master:

plain 复制代码
git push origin master

注意:Cherry-pick 会生成一个新的 commit id。若此后你想要让 dev 再次合并到 master,通常需要先在 dev 上执行 rebase 以避免重复或冲突。

八、总结

  • 使用场景
    • Cherry-pick:只需引入某几个提交,常用于补丁、紧急修复或"选取部分功能"。
    • Merge/Rebase:需整合整个分支的提交,确保功能完整对齐。
  • 注意事项
    • Cherry-pick 会产生新的 commit id,与原分支提交不同;后续若要整体合并分支,需小心重复提交或冲突。
    • 若操作前已在公共远程仓库同步,Rebase 或重写历史要谨慎,以免影响他人。
  • 最佳实践
    • 在提交信息中使用 -x 等方式记录来源 commit,便于后续排查。
    • 需要多次 Cherry-pick 时,可先用 -n 累积修改,然后一次性提交,避免产生大量碎提交。
    • 团队协作要约定好何时使用 Merge、何时使用 Rebase、何时使用 Cherry-pick,保证历史清晰可维护。
引用/参考
相关推荐
七灵微33 分钟前
ES6入门---第三单元 模块三:async、await
前端·javascript·es6
七灵微3 小时前
ES6入门---第二单元 模块五:模块化
前端·ecmascript·es6
m0_616188494 小时前
vue3 - keepAlive缓存组件
前端·vue.js·缓存
lh_12545 小时前
Uni-app 组件使用
前端·javascript·uni-app
Kx…………5 小时前
Day3:设置页面全局渐变线性渐变背景色uniapp壁纸实战
前端·学习·uni-app·实战·项目
Q_Boom5 小时前
前端跨域问题怎么在后端解决
java·前端·后端·spring
搬砖工程师Cola5 小时前
<Revit二次开发> 通过一组模型线构成墙面,并生成墙。Create(Document, IList.Curve., Boolean)
java·前端·javascript
林十一npc5 小时前
Fiddler抓取APP端,HTTPS报错全解析及解决方案(一篇解决常见问题)
android·前端·网络协议·https·fiddler·接口测试
小妖6666 小时前
4个纯CSS自定义的简单而优雅的滚动条样式
前端·javascript·css
江沉晚呤时6 小时前
深入解析 .NET Kestrel:高性能 Web 服务器的架构与最佳实践
服务器·前端·.net