引言
在日常繁重的开发工作中,你是否正在经历如下场景:
-
在某个分支上修复了一个bug或者实现了某个小功能,而又不希望立即合并整个分支,这时你该如何把特定的提交应用到其他分支呢?
-
在生产环境中发现了一个bug,而这个bug已经在开发分支得到修复,为了快速解决问题,这时你该如何将修复bug的提交单独应用到生产分支?
-
在分支A上开发了一个新特性,而这个特性还未到合并到主分支的时候,但临时需要在分支B上启用这个特性,这时你该如何操作呢?。
-
在多人协作时,如果某人的提交是在你正在进行的工作之外,而你又急需这部分提交的代码,这时你该如获取提交的代码呢?
面对以上的开发场景有没有合适的命令来满足这些需求场景呢,此时有个git非常有用的命令可以满足你的需求,那就是 git cherry-pick
命令了。
基本概念及用法
git cherry-pick
是 Git
版本控制系统中的一个重要命令,它允许你将任意分支上的某个或某些特定提交(以 commit hash
标识)的更改应用于当前所在分支,而不是进行完整分支的合并。执行 cherry-pick
后,Git
会将目标提交的更改在当前分支上重新创建一个新的提交,保持了原有提交的更改内容,但生成了新的提交 ID
。
使用 git cherry-pick
的命令格式如下:
bash
git cherry-pick <commit-hash>
其中 <commit-hash>
是你需要复制到当前分支的提交哈希值。一旦执行该命令,Git
将会尝试将指定提交的内容在当前分支上重现。
实战应用场景
跨分支移植补丁: 假设你在开发分支上修复了一个bug,但尚未准备好合并整个分支。这时,你可以使用 git cherry-pick
将该修复提交应用到生产分支,快速解决线上问题。
提取特定功能: 在分支A上开发了一个新功能,但由于计划安排暂时不能将其合并到主分支。若另一分支B需要临时拥有这个功能,可通过 git cherry-pick
将该功能提交转移到分支B。
解决冲突: 当多个开发者在不同分支上工作时,可能在不同的上下文中解决了相同的问题。通过 git cherry-pick
,可以将一个开发者修复的解决方案单独应用到其他分支,而无需进行复杂的合并操作。
同步独立更改: 即使在不同的开发路径上,也可能存在独立的、可以通用的代码更改。使用 git cherry-pick
,可以迅速将这些有价值的更改推广到其他相关的分支。
以上应用场景具体操作如下(假如master分支某个提交应用到develop分支上):
- 1.确保你已经切换到了想要应用补丁的目标分支:
bash
λ git checkout develop
Switched to branch 'develop'
- 2.获取你想移植的提交哈希(
commit hash
)。这可以通过查看历史提交记录找到,比如在Git
的图形界面工具中,或者在命令行中使用git log
命令列出提交历史,找出包含所需补丁的提交。
bash
λ git log --graph --oneline --all
* ca8c580 (origin/master, master) 修改编辑内容
* 761ab26 修改文案
* 99c3403 新增仓库地址和仓库
| * c8b94bb (HEAD -> develop, origin/develop) 文件冲突修改
| |\
| |/
|/|
* | 79f1d47 修改远程地址
| * 244769e 修改
|/
* bc24df0 Merge branch 'develop' of https://xx/xxxx/vite
|\
| * ac6412d Merge branch 'master' of https://xx/xxxx/vite into develop
| |\
* | | ba4a42a 需改
* | | 568d688 Merge branch 'develop' of https://xx/xxxx/vite
|\| |
| |/
|/|
| * f1dd49b 提交数据
| * 9d13341 修改
* | c664fcd update src/App.css.
* | ecdb5a5 update src/App.tsx. 文本修改
|/
* f1f4088 新建项目
- 3.执行
git cherry-pick
命令,后面跟上你想要移植的提交哈希:
bash
# 选择master分支提交的761ab26 应用到develop分支上
λ git cherry-pick 761ab26
Auto-merging src/App.tsx
[develop 55b234d] 修改文案
Date: Tue Mar 5 15:03:42 2024 +0800
1 file changed, 1 insertion(+), 1 deletion(-)
- 4.
Git
会尝试将指定提交所做的所有更改应用到当前分支。如果没有冲突,Git
将自动创建一个新的提交,这个提交包含了与原提交相同的更改,但具有新的提交哈希。
bash
# 应用develop分支前的日志如下
λ git log --graph --oneline
* c8b94bb (HEAD -> develop, origin/develop) 文件冲突修改
|\
| * 79f1d47 修改远程地址
* | 244769e 修改
|/
...
#应用develop分支后的日志如下:
λ git log --graph --oneline
* 55b234d (HEAD -> develop) 修改文案
* c8b94bb (origin/develop) 文件冲突修改
|\
| * 79f1d47 修改远程地址
* | 244769e 修改
|/
...
-
- 如果在应用更改时出现冲突,
Git
会暂停cherry-pick
过程并提示你解决冲突。
- 如果在应用更改时出现冲突,
bash
λ git cherry-pick 99c3403
Auto-merging src/App.tsx
CONFLICT (content): Merge conflict in src/App.tsx
error: could not apply 99c3403... 新增仓库地址和仓库
hint: After resolving the conflicts, mark them with
hint: "git add/rm <pathspec>", then run
hint: "git cherry-pick --continue".
hint: You can instead skip this commit with "git cherry-pick --skip".
hint: To abort and get back to the state before "git cherry-pick",
hint: run "git cherry-pick --abort".
打开冲突文件,手动编辑以解决冲突,保存修改后,执行
bash
λ git add <conflicted-file>
对所有冲突文件重复上述操作。但是不要进行任何commit
操作,或者会结束后续的cherry-pick
过程,如果进行commit
操作,则提交内容直接应用到当前分支了。
- 6.解决所有冲突后,继续完成
cherry-pick
过程:
bash
λ git cherry-pick --continue
- 7.如果在解决冲突后决定不再应用此补丁,可以取消
cherry-pick
操作:
bash
git cherry-pick --abort
通过以上步骤,你成功地将单个补丁从源分支移植到了目标分支,而且这个移植的过程会以一个新的提交形式记录在目标分支的历史中。记得在完成操作后及时推送到远程仓库,以便队友能获取到最新的更改。
写在最后
git cherry-pick
是一个强大而灵活的工具,它在版本控制和协作过程中扮演着至关重要的角色。通过精确选择和迁移单个提交,开发团队可以有效地复用代码、隔离修复、实现跨分支的增量更新,从而大大提高工作效率和代码质量。熟练掌握并适时运用 git cherry-pick
,无疑会使你的 Git
工作流更为高效和优雅。
喜欢的话帮忙点个赞 + 关注吧,将持续更新 Git
相关的文章,还可以关注我的公众号 梁三石FE
,感谢您的关注~