git cherry pick
本文最后更新于:2023-05-18 09:33:19
git cherry pick
如果你在使用 git 进行多人协作的代码管理,合并代码( git merge )的操作你一定不陌生。 git merge 会将指定分支的所有提交历史合并到当前所在的分支,它的合并单位是“分支”。但有的时候,我只想取某个分支的某几个提交的内容来合并。
遇到这种操作需求,我们可以使用 cherry-pick 命令,它是以“提交”为单位的合并,可以帮助你安全快速地达到目的。
cherry-pick 命令官方介绍
git-cherry-pick 它可以在当前分支应用其他已经存在的 commit 修改,并对每一个合并过来的 commit 产生一个新的提交记录(commit hash)。
cherry-pick - Given one or more existing commits, apply the change each one introduces, recording a new commit for each.
cherry-pick 的使用
基本命令
指定任何本地分支上的某个存在的提交git cherry-pick <commitHash>
例如代码仓库有两个分支 dev 和 feat:1
2
3
4
a - b - c - d - e #dev
\
f - g - h - i #feat现在要将 feat 分支上的提交 g 应用到 dev 分支:
1
2git checkout dev
git cherry-pick g代码库的结构将变成:
1
2
3a - b - c - d - e - g‘ #dev
\
f - g - h - i #featdev 分支后面将会增加一个提交 g’,这个提交的 commit 信息跟 feat 分支的 g 提交默认是一样的(你可以在提交过程中用 -m 选项追加内容,或者在处理冲突之后在 –continue 的时候修改,不过大部分时候,使用默认的就可以),但是会产生一个新的 commitHash。
转移多个提交
多个不连续的提交,提交之间用空格相隔
git cherry-pick <commitHash1> <commitHash2>
连续的提交(左开右闭),使用..注意中间没有任何空格
git cherry-pick <start-commitHash>..<end-commitHash>
连续的提交(左闭右闭)给第一个提交右侧加上^符号
git cherry-pick <start-commitHash>^..<end-commitHash>
注:连续的提交命令中,start-commitHash 一定要是 end-commitHash 之前的提交,否则命令将会失败,但不会报错。
转移最顶端的提交
git cherry-pick <branchName>
会将指定分支的最后一次提交应用到当前分支。转移另一个代码库的提交
其实 cherry-pick 的奥义就是,只要是在一个.git仓库管理下的本地代码,任何提交都可以被应用到任何可访问的本地分支,哪怕是跨代码库:1
2
3
4git remote add repo2 git@xxx.git # 添加另一个代码库
git fetch repo2 # 抓取新代码库到本地
git log repo2/master # 查看新代码库master分支的提交记录
git cherry-pick <commitHashInRepo2> # 将新的代码库的某个提交应用到当前分支(跨代码库的合并)冲突处理
如果在cherry-pick的过程中,代码产生了冲突,cherry-pick 会停下来,等待我们的下一步操作决策。处理冲突。我们可以先将代码冲突在编辑器中处理好,然后回到命令行,使用 –countinue 参数让 cherry-pick 过程继续执行:
git cherry-pick --countinue
放弃合并,代码回到操作前的样子
git cherry-pick --abort
退出cherry-pick,但是代码不回到操作前的样子
git cheerry-pick --quit
cherry-pick 的一些常用配置项
-n, –no-commit
只更新工作区和暂存区。不产生新的提交-x
在提交信息末尾追加一行(cherry picked from commit…)方便以后查到这个提交是如何产生的。-m parent-number, –mainline parent-number
如果原始分支是一个合并节点,那么 cherry-pick 默认会失败,因为不知道应该采用哪个分支的代码变动。 -m 配置项告诉 git 应该采用哪个分支分变动,parent-number 代表原始提交的父分支编号。git cherry-pick -m 1 <commitHash>
一般1号父分支是接受变动分支(the branch being merged into),2号父分支是作为变动来源的分支(the branch being merged from)。
参考
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!