告别全量合并git cherry-pick巧摘樱桃实现版本合并的“精准打击”

阿里云教程4个月前发布
33 0 0

什么是 Git Cherry-Pick?

简单来说,git cherry-pick 的作用是 “摘取”一个或多个已有的提交,然后将它们作为一个新的提交应用到当前分支上

你可以把它想象成从一棵树(分支)上摘下一颗或几颗特定的樱桃(提交),然后把它们挂到另一棵树上。这个过程不会移动原来的樱桃,而是创建了一份副本。

核心概念: 它应用的是 提交引入的更改,而不是直接移动提交本身。


为什么需要使用 Cherry-Pick?

git cherry-pick 的典型使用场景包括:

  1. 1. 修复漏洞的“神兵利器”
  2. 场景:你在 master 分支上修复了一个紧急漏洞,并进行了提交。但目前,这个漏洞在还在开发的 develop 分支和已经发布的 v1.0 分支上也存在。
  3. 解决:你切换到 develop 和 v1.0 分支,然后使用 cherry-pick 将修复漏洞的那个提交单独“摘”过来应用,而无需合并整个 master 分支。
  4. 2. 不小心在错误的分支上提交了代码
  5. 场景:你本应在 feature/login 分支上开发,却不小心在 develop 分支上提交了几个文件。
  6. 解决
  7. • 在 develop 分支上,使用 git log 找到错误提交的哈希值。
  8. • 切换到正确的 feature/login 分支。
  9. • 执行 git cherry-pick <提交哈希>,将这次提交应用到 feature/login 分支。
  10. • 回到 develop 分支,使用 git reset 回退掉那个错误的提交。
  11. 3. 只想应用某个功能的一部分提交
  12. 场景:一个功能分支 feature/A 有10个提交,但你只想将其中的第3、第7个提交引入到主分支,由于它们包含了一些可复用的组件或修复。
  13. 解决:在主分支上,直接 cherry-pick 那两次特定的提交。
  14. 4. 移植特定提交:在不同但具有类似代码库的项目间移植某个特定的补丁或功能。

基本语法与用法

1. 摘取单个提交

git cherry-pick <commit-hash>
  • • <commit-hash> 是你想要摘取的提交的哈希值,一般取前7位即可(如 a1b2c3d)。

示例:
假设我们想将提交 a1b2c3d 应用到当前分支。

# 1. 第一,确保你位于目标分支上(列如 develop)
git checkout develop

# 2. 执行 cherry-pick
git cherry-pick a1b2c3d

执行成功后,Git 会在 develop 分支上创建一个新的提交,这个新提交引入的更改与 a1b2c3d 完全一样,但会有一个新的哈希值。

2. 摘取多个提交

你可以一次指定多个提交,它们会按提交历史的顺序被依次应用到当前分支。

# 摘取一系列连续的提交(不包含结束点,类似于 log)
git cherry-pick <start-commit-hash>^..<end-commit-hash>

# 或者摘取多个不连续的提交
git cherry-pick <commit-hash-1> <commit-hash-2> <commit-hash-3>

示例:

# 将提交 A 到 D(不包括A,包括D)之间的所有提交应用到当前分支
git cherry-pick A^..D

# 或明确指定三个不连续的提交
git cherry-pick a1b2c3d e4f5g6h i7j8k9l

3. 常用选项

  • -n / –no-commit
    • • 摘取更改,但不会自动创建提交。它会将更改放入暂存区和工作区,允许你手动修改后一次性提交。
    • 适用场景:当你需要将多个 cherry-pick 的更改合并为一个提交,或者想在提交前做些微调时。
    • • git cherry-pick -n a1b2c3d
      # … 修改一些东西 …
      git commit -m “手动合并了cherry-pick的更改和一些调整”
  • -x
    • • 在提交信息中附加一行(cherry picked from commit …),说明这个提交是从哪里摘取来的。这对于跟踪和审计超级有用。
    • 注意:一般只在公共分支(如 master, develop)上使用,在私有功能分支上没必要。
  • -s / –signoff
    • • 在提交信息的末尾添加一行 Signed-off-by: 签名。
  • -e / –edit
    • • 允许你在创建新提交前编辑提交信息。
  • –abort
    • • 当 cherry-pick 过程中发生冲突,你想撤销整个操作并回到操作前的状态。
    • • # 发生冲突后…
      git cherry-pick –abort
  • –continue
    • • 当你手动解决了冲突后,使用此命令继续完成 cherry-pick 过程。
    • • # 解决完所有冲突,并用 git add . 标记为已解决后…
      git cherry-pick –continue

处理冲突

和 merge 或 rebase 一样,cherry-pick 也可能发生冲突。

处理流程:

  1. 1. Git 会暂停操作,并告知你哪些文件冲突了。
  2. 2. 手动解决冲突:用编辑器打开冲突文件,解决 <<<<<<<, =======, >>>>>>> 标记的部分。
  3. 3. 标记冲突已解决:使用 git add <file-path> 或 git add . 将解决后的文件加入暂存区。
  4. 4. 继续操作:执行 git cherry-pick –continue 来完成整个过程。
  5. 5. 或者放弃:如果冲突太复杂想放弃,执行 git cherry-pick –abort。

最佳实践与注意事项

  1. 1. 慎用原则:cherry-pick 很强劲,但不要滥用。它破坏了提交历史的线性,可能会导致历史混乱。在团队协作中,合并 一般是更被推荐的方式。
  2. 2. 主要用于修复漏洞:它的王牌场景就是在多个分支间 backport 或 forward-port 修复补丁。
  3. 3. 理解“副本”本质:记住,cherry-pick 创建的是新提交,它们和原提交除了更改内容一样外,是完全独立的。
  4. 4. 小心依赖关系:如果你摘取的提交依赖于之前的其他提交,可能会由于缺少依赖而引入不完整的功能或错误。确保你摘取的提交是自包含的。

总结

场景

命令示例

说明

应用一个修复

git cherry-pick a1b2c3d

最常用,直接应用特定提交

应用多个修复

git cherry-pick A^..C

将A之后到C的提交按顺序应用

应用但不提交

git cherry-pick -n a1b2c3d

方便与其他修改合并后一起提交

记录来源

git cherry-pick -x a1b2c3d

在信息中记录原提交,便于追溯

解决冲突后继续

git cherry-pick –continue

标准冲突解决流程

放弃操作

git cherry-pick –abort

冲突太复杂时回退到操作前状态

希望这份详细的讲解能协助你成为 git cherry-pick 的使用专家!它是一个在特定场景下能极大提升效率的工具,但务必牢记“能力越大,责任越大”。

© 版权声明

相关文章

暂无评论

none
暂无评论...