拣选会提取某次提交的补丁,之后尝试将其重新应用到当前分支上。 这种方式在你只想引入特性分支中的某个提交时很有用。

假设你的项目提交历史如下:

如果你希望将提交 e43a6 拉取到 master 分支,你可以运行:

# 当前处于 master 分支

$ git cherry-pick e43a6
Finished one cherry-pick.
[master]: created a0a41a9: "More friendly message when locking the index
fails."
3 files changed, 17 insertions(+), 3 deletions(-)

这样会拉取和 e43a6 相同的更改,但是因为应用的日期不同,你会得到一个新的提交 SHA-1 值。 现在你的历史会变成这样:

现在你可以删除这个特性分支(ruby_client),并丢弃不想拉入的提交(5ddae)。

需要说明的是,提取某次提交的“补丁”,这个补丁是基于其父提交的。

下图可以说明:

我们要拣选提交 C4 到 maint 分支(maint 指向 C7),Git 会生成一个补丁(Δ=C4−C3 \Delta = C4-C3Δ=C4−C3),然后把Δ \DeltaΔ应用到C7上,也就是说把 C4 对 C3 的变化在 C7 上重放一遍。

为何会产生冲突
同 merge 操作一样,拣选操作也可能产生冲突。有人会问:不会吧,打个补丁也能冲突?

当然能。

用 diff 工具生成 patch 时,我们所做的每一处修改都会连同它的“定位信息”(原始文件中的行号、修改处前三行和后三行的原始文本)一并保存到 patch 文件中。patch 被应用时,会在目标文件中寻找“定位信息”,找到后再实施修改。可是,当我们把补丁应用到 C7 上时,有可能找不到那些定位信息了:在master分支上,C2变成了C3,在maint分支上,C2变成了C6,又变成了C7,也许C3和C7相差越来越远,C3中的上下文在C7中早已面目全非,不见踪迹。于是应用patch失败,即发生冲突。

冲突了怎么办
当拣选发生冲突的时候,GIT 会采用三路合并算法。还是以上面的图为例子,

当你运行命令 git cherry-pick C4 的时候,Local是C7,Remote是C4,Base是C3(即C4的父提交)。总结:

当你运行命令

git cherry-pick <commit C>

如果冲突了,那么Git会尝试三方合并

LOCAL: the commit you’re merging on top of (i.e. the HEAD of your branch)
REMOTE: the commit you’re cherry picking (i.e. commit C)
BASE: the parent of the commit you’re cherry-picking (i.e. C^, ie the parent of C)
如果三方合并的时候又冲突了怎么办?那只能靠我们人工解决了。

参考资料
【0】《Pro Git》(Scott Chacon, Ben Straub Version 2.1.14, 2018-05-19)

【1】 https://my.oschina.net/jiangyouxin/blog/108717

【2】《Git 高手之路》,人民邮电出版社

【3】 StackOverflow, https://stackoverflow.com/questions/10058068/in-a-git-cherry-pick-or-rebase-merge-conflict-how-are-base-aka-the-ancestor
---------------------
来源:CSDN
原文:https://blog.csdn.net/longintchar/article/details/83473594

cherry-pick 命令的更多相关文章

  1. git之rebase、merge和cherry pick的区别(面试常问)

    git flow图例镇楼 merge 这个简单,初学者常用.比如主分支是Dev,最新版本是01.然后小明基于此,搞了个feature 分支A,业务:打酱油.然后在上面多次提交,完成功能迭代开发,如A1 ...

  2. git gui 还原部分提交文件

    有时候用git提交文件的时候会一起提交了多个文件,但是突然后悔了,想把其中一个文件撤销提交,其他文件不做修改.这个时候该怎么办呢? 我觉得有很多办法,比如可以先checkout到上次的提交,然后复制要 ...

  3. gerrit 使用教程(一)

    原文地址:https://www.jianshu.com/p/b77fd16894b6 1, Gerrit是什么? Gerrit实际上一个Git服务器,它为在其服务器上托管的Git仓库提供一系列权限控 ...

  4. Git速成学习第六课:Bug分支

    Git速成学习笔记整理于廖雪峰老师的官网网站:https://www.liaoxuefeng.com/ 当你接到一个修复代码为101的任务的时候,很自然的你想创建一个分支issue-101来修复它,但 ...

  5. [git]图解git常用命令

    本文图解git中最常用的命令.如果你稍微理解git的工作原理,这篇文章能够让你理解的更透彻. 基本用法 约定 命令详解 Diff Commit Checkout Detached HEAD(匿名分支提 ...

  6. ###Git 基础图解、分支图解、全面教程、常用命令###

    一.Git 基础图解 转自:http://www.cnblogs.com/yaozhongxiao/p/3811130.html Git 图解剖析 git中文件内容并没有真正存储在索引(.git/in ...

  7. 图解Git命令

    上面的四条命令在工作目录.暂存目录(也叫做索引)和仓库之间复制文件. ·git add files把当前文件放入暂存区域. ·git commit 给暂存区域生成快照并提交. ·git reset - ...

  8. Git命令速查

    Alias 下面的只是例子,想改成什么跟随自己的意愿即可. git config --global alias.st status //status 缩写成 st git config --globa ...

  9. Git 经常使用命令合集

    ====== Git 经常使用命令合集 ====== === 1.Git 文档 ===     Git 中文文档观看地址:http://git.oschina.net/progit/      === ...

  10. 图解Git命令【转】

    本文转载自:https://github.com/geeeeeeeeek/git-recipes/wiki/4.1-%E5%9B%BE%E8%A7%A3Git%E5%91%BD%E4%BB%A4 此页 ...

随机推荐

  1. 【363】python 相关小技巧

    1. 对列表进行乱序 通过 random.shuffle() 方法实现,直接对列表进行操作 >>> import random >>> a = list(range ...

  2. Linux find命令使用方法

      Linux中find命令用来在指定目录下查找文件.通过组合不同参数可以在linux系统中快速查找需要的文件或目录. find命令语法 格式:find pathname -options [ -pr ...

  3. ARP工作过程、ARP欺骗的原理和现象、如何防范ARP欺骗

      地址解析协议(Address Resolution Protocol,ARP)是在仅知道主机的IP地址时确定其物理地址的一种协议. 下面假设在一个局域网内,主机A要向主机B发送IP数据报. ARP ...

  4. split()方法解析

    split()方法用于将字符串分割为字符串数组. 废话不多说,直接贴代码: var str="How are you doing today?" console.log(str.s ...

  5. 检测浏览器是否支持cookie功能

    <script> if(navigator.cookieEnabled) { document.write("你的浏览器支持cookie功能!"); } else{ d ...

  6. 第三条博客 你好 Java web!

    今天周五了,明天就是周末!第一个周末就这样结束了 今天我学习了MyEclipse开发 Javaweb 程序,学的是最基础的那一部分 首先先创建了自己的项目,展开项目标签,编辑index.jsp. 我还 ...

  7. 使用firefox插件httperrequest,模拟发送及接收Json请求 【转】

    转自[http://blog.csdn.net/feixue1232/article/details/8535212] 目标:使用httpreques\Json-Handle\tcpdump\wire ...

  8. echart生成饼状图

    //绘制图表. echarts.init(document.getElementById('main')).setOption({ tooltip : { trigger: 'item', //触发类 ...

  9. jar is specified twice.

    Warning:Exception while processing task java.io.IOException: The same input jar [libs\afinal_0.5.1_b ...

  10. Java 动态代理 两种实现方法

    AOP的拦截功能是由java中的动态代理来实现的.说白了,就是在目标类的基础上增加切面逻辑,生成增强的目标类(该切面逻辑或者在目标类函数执行之前,或者目标类函数执行之后,或者在目标类函数抛出异常时候执 ...