日常开发里经常会遇到这种场景:在 master 上修了个小 bug,但还有另一个长期分支 add_function 也需要这个修复,可又不想把整个 master 合进去。git cherry-pick 正是为这种「只挑一个 commit 搬走」的需求设计的。

使用场景

  • 想把某个分支上的单个或少数几个 commit 应用到当前分支;
  • 不希望像 merge 那样把整条历史一并带过来;
  • 也不想像 rebase 那样改写整条分支的提交。

操作步骤

1. 同步本地 master

确保源分支是最新的,避免 cherry-pick 到已被覆盖或回滚的旧 commit:

1
2
git checkout master
git pull origin master

2. 切到目标分支

1
git checkout add_function

后续 cherry-pick 出来的新 commit 会落在当前所在的分支上。

3. 找到要复制的 commit hash

1
git log --oneline master

--oneline 一行一个 commit,便于快速定位。复制出目标 commit 的前 7~12 位 hash 即可。

4. 执行 cherry-pick

1
git cherry-pick <commit-hash>

如果要一次搬多个,可以连写:

1
git cherry-pick <hash1> <hash2> <hash3>

或者用区间(注意是左开右闭,不包含 A,包含 B):

1
git cherry-pick A..B

5. 推送到远端

1
git push origin add_function

遇到冲突怎么办

cherry-pick 在被搬的 commit 与目标分支有差异时可能产生冲突。Git 会暂停操作并把冲突文件标出来,处理流程如下:

  1. git status 查看冲突文件;

  2. 手动编辑文件,删掉 <<<<<<< / ======= / >>>>>>> 标记,保留想要的内容;

  3. 把解决后的文件加入暂存区:

    1
    git add <file>
  4. 继续 cherry-pick:

    1
    git cherry-pick --continue

如果中途想放弃整个操作:

1
git cherry-pick --abort

如果想跳过当前这个有冲突的 commit、继续后面的:

1
git cherry-pick --skip

几个小提醒

  • cherry-pick 出来的 commit hash 会变——它在新分支上是一次新的提交,作者信息和 message 保留,但父 commit 不同。

  • 同一个改动如果先 cherry-pick 再 merge 回去,可能产生「重复提交」的视觉冗余,但通常不会冲突;如果两边后续又各自修改了同一段代码,再合并时仍可能冲突。

  • 如果想保留「这个 commit 是从哪儿挑过来的」信息,加 -x 选项,会在 commit message 里附上 (cherry picked from commit ...)

    1
    git cherry-pick -x <commit-hash>

参考