git cherry-pick用法

git cherry-pick 用来把某一个提交,或者某几个指定提交,复制到当前分支上。

它比较适合下面这些场景:

  • 线上分支修了一个 bug,想把这次修复同步到开发分支
  • 某个功能分支里只有一两个提交有用,不想整条分支都合并进来
  • 想把别的分支上的某次提交单独拿过来,而不是执行 merge

一、先理解 cherry-pick 做了什么

假设现在有两个分支:

  • main
  • feature

feature 分支上有一个提交修复了接口错误,你现在在 main 分支,也想要这个修复。

这时可以直接把那次提交挑过来:

git checkout main
git cherry-pick 提交ID

执行后,Git 会把那次提交的改动应用到当前分支,并在当前分支生成一个新的提交。

要注意的是,这不是“移动”原提交,而是“复制一份改动内容”到当前分支,所以新生成的提交 ID 一般会和原来不同。

下面这张图可以直观看一下这个过程:

二、最常见的基本用法

先查看提交记录:

git log --oneline

假设你看到 feature 分支里有这样一条提交:

a1b2c3d 修复订单接口参数错误

切换到目标分支后执行:

git checkout main
git cherry-pick a1b2c3d

如果没有冲突,这次提交就会被应用到 main 分支。

再执行:

git log --oneline

通常就能看到当前分支多出了一条内容相同、但提交 ID 不同的新提交。

三、一次挑选多个提交

1. 逐个写出多个提交 ID

如果要挑多个不连续的提交,可以直接把提交 ID 都写上:

git cherry-pick a1b2c3d d4e5f6g h7i8j9k

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

2. 挑选一段连续提交

如果这些提交是连续的,可以用范围:

git cherry-pick 起始提交ID^..结束提交ID

例如:

git cherry-pick a1b2c3d^..d4e5f6g

这里的意思是,把从 a1b2c3dd4e5f6g 之间的提交都挑过来,并且包含起始提交。

如果写成:

git cherry-pick a1b2c3d..d4e5f6g

那通常不包含 a1b2c3d 这次提交,这一点要特别注意。

四、只应用改动,先不自动提交

有时候你想先把改动拿过来,再自己检查一下,或者和当前工作区里的其他修改一起提交,这时可以加 -n 参数:

git cherry-pick -n a1b2c3d

-n--no-commit 的简写。

它会把改动应用到当前工作区和暂存区,但不会自动生成提交。

这时你可以先查看状态:

git status

确认没问题后再自己提交:

git commit -m "引入订单接口修复"

五、发生冲突时怎么处理

cherry-pickmerge 一样,也可能出现冲突。

比如当前分支和目标提交都修改了同一段代码,执行后可能会看到冲突提示。

这时处理步骤通常是:

1. 查看冲突文件

git status

2. 手动修改冲突内容

把冲突标记处理掉,保留你真正想要的代码。

3. 标记冲突已解决

git add 冲突文件

4. 继续执行

git cherry-pick --continue

如果你处理中途发现这次挑选不要了,也可以取消:

git cherry-pick --abort

它会回到执行 cherry-pick 之前的状态。

六、和 merge 的区别

很多人第一次接触 git cherry-pick 时,容易把它和 merge 混在一起。

简单来说:

  • git merge 是把一个分支整体合并过来
  • git cherry-pick 是只拿指定提交过来

如果你只想同步一个 bug 修复、一个小功能、一次配置调整,那么 cherry-pick 往往更直接。

但如果你需要把一整条分支的历史完整合并,通常还是 merge 更合适。

七、常见使用场景

1. 把线上 hotfix 同步回开发分支

比如你在 main 分支紧急修了一个线上问题,但开发工作还在 dev 分支继续进行。

这时可以切到 dev,把 main 上那次修复挑过来:

git checkout dev
git cherry-pick 修复提交ID

这样就不需要把整个 main 分支重新合并一遍。

2. 只拿功能分支里的某一次提交

有些功能分支提交很多,里面可能既有实验代码,也有真正需要的修改。

如果当前只想引入其中某一个提交,cherry-pick 会比 merge 更省事。

3. 补漏同步

有时两个分支长期并行开发,某个重要提交漏同步了,这时也可以直接用 cherry-pick 补过去。

八、常见问题

1. cherry-pick 后为什么提交 ID 变了?

因为 Git 会在当前分支重新创建一个新提交。

虽然改动内容可能一样,但它已经是另一条提交记录了,所以提交 ID 通常不同。

2. 可以对已经 merge 过的提交再执行 cherry-pick 吗?

可以,但要小心重复改动。

如果那部分代码其实已经在当前分支里了,再次执行可能会出现冲突,或者产生重复提交。

执行前最好先用 git loggit show 看清楚目标提交内容。

3. cherry-pickrebase 是不是一回事?

不是。

rebase 主要是变更提交基底、整理提交历史;
cherry-pick 主要是挑选指定提交并复制到当前分支。

两者都可能改写历史,但使用目的不一样。

九、小结

git cherry-pick 最核心的作用,就是把指定提交复制到当前分支。

最常用的几种写法:

git cherry-pick 提交ID
git cherry-pick 提交ID1 提交ID2
git cherry-pick 起始提交ID^..结束提交ID
git cherry-pick -n 提交ID
git cherry-pick --continue
git cherry-pick --abort

如果你只想拿某几个提交,而不想整条分支都合并进来,这个命令会非常方便。

参考文章