git cherry-pick
git cherry-pick
命令允许你选择一个或多个在其他分支上已经存在的提交 (commits),并将它们应用到当前所在的分支上。它不像 git merge
或 git rebase
那样合并整个分支的历史,而是精确地复制选定的提交。
git cherry-pick
的主要用途:
- 应用单个 Bug 修复或小功能到多个分支:
例如,你在dev
分支上修复了一个紧急 bug,并希望将这个修复应用到master
分支(可能还有其他发布分支),而不需要合并整个dev
分支。 - 避免不必要的合并:
当一个分支的更改非常庞大,但你只需要其中几个特定的提交时,cherry-pick
可以避免引入大量无关的更改。 - 从错误的分支中“挽救”提交:
如果你不小心在一个错误的分支上做了提交,并且希望把它移动到正确的开发分支上,cherry-pick
可以帮助你。
git cherry-pick
的工作原理:
当你对一个提交执行 cherry-pick
时:
- Git 会找到该提交所引入的所有更改。
- 然后尝试将这些更改应用到你当前的分支上。
- 如果应用成功,Git 会在当前分支创建一个新的提交,这个新提交的内容与原始提交的内容完全相同,但哈希值不同(因为它是新的提交,在新的位置)。
示例场景:
假设你有两个分支:master
和 feature-x
。你在 feature-x
分支上做了两个提交:C1
和 C2
。现在,你发现 C1
是一个非常重要的优化,你想把它单独应用到 master
分支,而不把 feature-x
上的 C2
或其他未来的提交也带过来。
-
查看
feature-x
分支的提交历史:
首先,确保你了解feature-x
上的提交哈希值。1git log feature-x --oneline
输出可能看起来像这样:
abcdef1 C2: Add new feature part B 1234567 C1: Optimize database query
假设
C1
的哈希值是1234567
。 -
切换到目标分支 (
master
):1git checkout master
-
执行
cherry-pick
:1git cherry-pick 1234567
-
解决冲突 (如果发生):
如果在应用1234567
这个提交时,master
分支上存在与该提交冲突的更改,Git 会暂停并提示你解决冲突。- 手动编辑冲突文件,解决冲突。
- 使用
git add <冲突文件>
标记文件已解决。 - 使用
git cherry-pick --continue
继续操作。 - 如果你想放弃
cherry-pick
,可以使用git cherry-pick --abort
。
-
查看结果:
成功执行后,master
分支的提交历史会多出一个新的提交,这个新提交的内容与1234567
提交完全一致。1git log --oneline
你会看到
master
分支上现在有了1234567
的一个副本(新的哈希值)。
高级用法:
-
cherry-pick
多个提交:
你可以一次cherry-pick
多个提交,按顺序应用。1git cherry-pick <commit-hash-1> <commit-hash-2> ...
-
cherry-pick
一个提交范围:
例如,你想cherry-pick
从commitA
到commitB
(不包括commitA
)之间的所有提交。1git cherry-pick commitA..commitB
如果想包括
commitA
:1git cherry-pick commitA^..commitB
请注意,范围是
..
语法,后一个提交是包含的,前一个提交是不包含的。commitA^
表示commitA
的父提交,这样就可以包含commitA
本身。 -
cherry-pick -n
(不自动提交):
如果你想将提交的更改应用到工作区和暂存区,但不立即创建新的提交,可以使用-n
或--no-commit
。这允许你在提交之前做进一步的修改或合并多个 cherry-picked 的更改。1git cherry-pick -n <commit-hash> 2# ... 进行其他修改或 cherry-pick 3git commit
git cherry-pick
是一个非常强大的工具,但也要谨慎使用,因为它会创建新的提交,这可能会使历史记录稍微复杂化,尤其是在多个分支之间来回 cherry-pick 相同的更改时。