搞懂 git cherry-pick,这篇就够了!
哈喽,大家好!今天我们来聊聊 Git 里面一个非常实用的命令——git cherry-pick。
你可能会有疑问,已经有了 merge 和 rebase,为什么还需要 cherry-pick 呢?别急,听我慢慢道来。
cherry-pick 是什么?
cherry-pick,顾名思义,就是“摘樱桃”。在 Git 的世界里,我们可以把它理解为“挑选提交”。它的作用就是将一个或多个指定的提交(commit)从一个分支“复制”到当前所在的分支。
这里要注意,说是“复制”,其实 Git 会在当前分支上创建一个新的提交,这个新提交包含了被“摘”过来的提交的所有代码变更。虽然提交信息、作者等元数据可以保持一致,但它们的哈希值(commit ID)是不同的。
什么时候适合用 cherry-pick?
设想一下,你是不是也遇到过下面这些场景:
- 紧急修复线上 Bug:线上版本出了个紧急 Bug,你在
hotfix分支上修复了它,并经过了测试。现在,你不仅需要将这个修复合并到master主干,也需要同步到正在开发的develop分支,以避免下一个版本再次出现同样的问题。这时候,cherry-pick就能大显身手,让你精确地只把修复 Bug 的那个提交应用到develop分支,而不会带上hotfix分支上其他的提交。 - “移植”某个功能:假设你在一个功能分支
feature-A上开发了几个功能,后来发现其中某个提交实现的功能,对于另一个功能分支feature-B来说也同样需要。你总不想再写一遍同样的代码吧?通过cherry-pick,你可以轻松地将那个特定的功能提交“移植”到feature-B分支。 - 从废弃的分支中“抢救”代码:有时候,一个功能分支可能因为需求变更等原因被废弃了,但其中有那么一两个提交还是有用的。
cherry-pick就像一个“代码救援队”,可以帮你把这些有价值的提交从即将被删除的分支里拯救出来。 - 提交错了分支:这绝对是手滑党们的痛。本来应该在
develop分支提交的代码,一不小心提交到了master。别慌,先切换回develop分支,然后用cherry-pick把那个提交“摘”回来,再把master分支上的错误提交 reset 掉,完美解决!
总而言之,当你需要将一个分支的部分代码变更应用到另一个分支时,cherry-pick 就是你的不二之选。
实战演练:cherry-pick 怎么用?
光说不练假把式,我们来看几个实例。
假设我们现在的分支情况是这样的:
a - b - c - d (master)
\
e - f - g (feature)
现在我们想把 feature 分支上的 f 这个提交应用到 master 分支。
1. 摘取单个提交
首先,切换到你的目标分支,也就是 master 分支:
git checkout master
然后,执行 cherry-pick 命令,后面跟上你要摘取的提交的哈希值:
git cherry-pick f
(这里的 ‘f’ 是 commit ‘f’ 的哈希值简写)
执行成功后,master 分支的提交历史会变成这样:
a - b - c - d - f' (master)
\
e - f - g (feature)
注意,f' 是一个新的提交,但它引入的变更和 f 完全一样。
2. 摘取多个提交
如果你想一次性摘取多个提交,比如 f 和 g,只需要把它们的哈希值依次列在后面,用空格隔开即可:
# 切换到 master 分支
git checkout master
# 摘取多个提交,建议按照提交的时间顺序
git cherry-pick f g
3. 摘取一个区间的提交
有时候你想摘取一个连续的提交区间。比如,我们想把 feature 分支上从 e 到 g 的所有提交都应用到 master 上。
- 不包含起始提交:
commit1..commit3表示从commit1之后到commit3的所有提交。
这就会把git cherry-pick e..g ``` 这会把 `f` 和 `g` 两个提交应用到当前分支。 * **包含起始提交**:如果你也想要 `e` 这个提交,可以使用 `^` 符号。 ```bash git cherry-pick e^..ge,f,g三个提交都应用过来。
可能会遇到的问题
冲突解决
cherry-pick 并非总是顺风顺水。如果在应用提交的过程中,Git 发现代码有冲突,它会停下来,等待你手动解决。
这个过程和解决 merge 冲突非常相似:
- 手动修改冲突文件,完成后
git add <文件名>。 - 执行
git cherry-pick --continue,让 Git 继续应用剩余的提交。 - 如果你中途想放弃,可以执行
git cherry-pick --abort,分支会恢复到cherry-pick之前的状态。
常用选项
cherry-pick 还有一些有用的选项,可以帮助你更好地控制整个过程:
-
--no-commit或-n:只将代码变更应用到工作区和暂存区,但不会自动生成新的提交。这给了你在提交前再次检查和修改代码的机会。 -
--edit或-e:在提交前,会打开编辑器让你重新编辑提交信息。 -
-x:在生成的提交信息的末尾,会自动加上一行(cherry picked from commit ...),方便追溯这个提交的来源。
cherry-pick 的优缺点
优点:
- 精确灵活:可以精确地选择需要的提交,而不是整个分支。
- 保持历史整洁:相比于为了一个小小改动而去
merge整个分支,cherry-pick可以让你的提交历史更加清晰。
缺点:
- 可能产生重复提交:如果在
cherry-pick之后,你又将整个分支merge到当前分支,可能会出现内容相同的重复提交。 - 丢失上下文:只复制代码变更,可能会丢失原始提交的上下文信息,给代码审查带来一定困难。
总结
git cherry-pick 是一个强大的工具,它赋予了我们“挑选”提交的能力,极大地提高了我们处理特定场景的灵活性。尤其是在处理紧急 Bug 修复和跨分支同步少量代码变更时,它的优势尤为明显。
不过,请记住,它并不是 merge 和 rebase 的替代品,而是一种补充。理解它的适用场景,并谨慎使用,才能真正发挥它的威力,让你的版本控制工作流更加高效和清晰!