【git】patch 补丁 (cherry-pick,rebase过程)

研究这个是因为cherry-pick命令引起的。还是之前那个事情,仔细还原一下:

我clone代码,然后基于master co一个dev的分支,然后开发开发开发。。。最后单元测试通过了,准备上测试环境。公司的测试环境是staging分支,然后我就本地co一个staging跟踪远程的staging分支,好了以后就需要把自己dev的分支开发的内容合到staging分支,如果staging此时和master一致,那么我这次merge就是一个fast-forward,很轻松。但是staging分支与master并不同步,大家用的时候可能很随意,导致staging分支此时和master差别很大,这时如果merge一下,需要处理太多冲突。

后来同事告我cherry-pick一下dev到staging,结果就只有几个改动,方便了很多。

这时我意识到了cherry-pick的妙处,就查了查这货到底干嘛的?网上说是把某一次提交 应用 到一个分支,而且!!!只应用指定的提交,不会包括之前的提交。正式因为cherry-pick这个特性,才解决了我上面提到的问题。

我看了以后先是觉得这个命令真的有用,然后仔细想想,这个到底是一个什么过程?如何只应用中间的一个提交???这个和merge什么区别???会到我上面的问题,dev和staging分支差别太大了,如果merge,那么需要把二者分叉之后的全部提交都合并,提交越多,冲突也越多。而cherry-pick只把指定的提交应用到分支上,所以只产生一次提交的冲突。

接下来的一个问题是,如何界定一次提交???在网上查阅了一些,最后在git手册上找到了比较权威的说法,那就是patch,补丁。补丁在rebase和cherry-pick中很有用。git中生成补丁的命令有diff和format-patch。该命令用于生成两个版本文件的差异。格式为git diff a b,就会生成从a版本到b版本的变动补丁,也就是如何由a变成b。format-patch会加上提交信息。举个diff的例子,a.txt,最开始是123,后面改成abc,

执行:

git diff HEAD HEAD^ > t.patch

就可以创建一个补丁,

cat t.patch

 

这是一种unix式的记录差异的方式,一种上下文式的形式。由于文件只有一行所以很简单。关于这个文件的格式可以上网上查找,很多。这里我想说的是git就是根据这个文件来打补丁的,具体怎么打?我猜测就是根据-和+来的,本来-和+是标识两个版本的文件的,但是我发现在git中,每一次修改剧本只有delete和insert,比如下面是我的一次提交:

 

并没有看到modify类似的,所以我猜测是是通过记录冲突行的来自两个版本的内容,也就是表示为-和+的部分,然后如果要从一个版本切换到另一个,只需要把当前文件中-的部分删除,+的部分保留即可。这样就可以很轻松的利用diff补丁文件实现版本的切换。

那么有一个问题是,既然补丁只能生成两个指定版本的差异,能否用在其他文件上?这个要看补丁的内容,打补丁严格按照diff来打,也就是把-的部分删除,那么需要打补丁的文件里必须在指定行有与-指定的一样的内容才行,否则这个补丁就找不到要删除的内容,就无法按照diff来操作了。

就像之前的例子,diff表明,必须要把第一行的abc删除,然后再第一行写入123。如果第一行没有abc,那么这个补丁就没法使用。

所以我新建了一个目录,开始创建一个新的a.txt,内容为hello,然后apply,结果:

果然不能用。再把a.txt改为abc,结果就可以了。由此可见,要想成功使用补丁,就必须明白补丁的内容是不是与待使用补丁的文件相吻合。

至此,就明白了补丁怎么生成,补丁怎么应用到文件,进而明白了rebase和cherry-pick的过程,以及什么时候rebase和cherry-pick会conflict,也就是补丁用不了的时候,就会提示我们解决。同时也帮我搞清楚了最开始的问题,为什么chery-pick可以只提交一个当前版本的改动。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值