(附Git的cherry pick神操作)如何解决gitlab合并分支请求时的代码改动(commits和changes)与本地分支的(commit&push)不一致的问题
(附Git的cherry pick神操作)如何解决gitlab合并分支请求时的代码改动(commits和changes)与本地分支的(commit&push)不一致的问题
目录
cherry pick(筛选合并)和 merge(合并)的区别:
问题现象
最近在项目中遇到一个问题:
使用IDEA开发工具在自己创建的代码分支(以下称“本地分支B”)上commit并push代码时,change记录是这样的:
可以看到本次提交到本地分支B的代码涉及到8个文件的改动,但是当我在gitlab上发起合并请求时,却发现commits数和changes数有异常:
遇到这种情况该如何解决呢?
问题分析
当我们发现gitlab合并分支请求时的代码改动(commits和changes)与本地分支的(commit&push)不一致时,这说明本次合并存在隐藏的代码差异问题,此时应该拒绝和关闭本次合并请求,不要进行代码合并。
那么,就来分析一下出现这个问题的原因吧!
操作步骤如下:
步骤1:
在IDEA开发工具中,切换到本地分支A,然后拉取远程分支A的最新代码。
步骤2:
基于本地分支A创建本地分支B。
步骤3:
在本地分支B改动代码、提交并推(commit&push)至远程分支B。
步骤4:
在gitlab上发起合并请求,合并本地分支B到远程分支A。
注意:
此时应该还未点击同意合并请求按钮(即本地分支B还未真正合并到远程分支A)。
已经点击了同意合并请求按钮(即本地分支B已经合并到远程分支A了)的场景在文末的最后一节【 拓展:步骤4的合并请求被同意后该如何解决?】中也会提到解决方法。
操作完上面这些步骤后,就出现了开头提到的问题现象。
但是认真梳理了这些操作步骤之后,并没有找到问题原因,因为这些步骤没有问题,那么问题到底是为啥呢?
经过我不断地测试和问题复现,才终于确定:上面这些操作步骤确实没有问题,而问题发生的原因其实是在这些操作步骤之前就存在了!!!
其实在很久之前,为了熟悉这个项目的代码,我拉取过这个项目的分支A代码到本地;不过当时还不需要参与该项目的开发工作,所以我直接在自己本地的分支A上进行了代码改动,以便进行本地debug测试,至于当时有没有把代码改动commit过?实在是不记得了。
后来还没参与这个项目的开发,就被调去其他项目了。直到最近突然又被调回这个项目,参与开发工作,然后第一次push代码就发生了这个问题;所以可以确定就是以前保存在我的本地分支A的代码存在的本地缓存导致的;
实际情况如下:
情况1:
在步骤1之后,实际上我本地分支A确实拉取了远程分支A的最新代码,但同时也夹杂着我以前的本地缓存代码。
情况2:
在步骤2之后,我的本地分支B的代码是基于本地分支A创建的。
情况3:
在步骤3提交时,只看到8个文件,是因为本次提交确实只有8个文件改动了。
情况4:
在步骤4合并分支代码时,看到commits和changes数量很大,这就说明在我执行步骤3之前,本地分支A其实已经commit(提交)过很多次代码了。
但是commits达到了800多次,这显然很不对劲!!!尽管我已经不记得以前是否真的有在本地分支A上面commit过代码了,但即使有,也绝不可能commit这么多次代码吧?
所以,难道是在步骤2时,先自动地commit了本地分支A的代码,然后再去创建本地分支B的?但是我按照这个猜测去实验了一下,发现无法复现,说明我这个猜想不对;反而确实是要在本地分支A上commit过后,能复现上面这个问题......
所以,尽管我实在不想承认,但这似乎就是事情的真相了(我完全不相信自己会在本地分支A上commit过800多次代码啊!!!)。
不过这已经不重要了,最重要的是找到问题并解决它,这样再下次遇到同样问题时,就能迎刃而解了。
解决方法
紧接上面的步骤4:
步骤5:
取消步骤4中申请的合并请求。
步骤6:
在IDEA开发工具中,先删除本地分支A(即清楚本地分支A的缓存),再重新checkout远程分支A到本地(即重新创建本地分支A,此时的本地分支A和远程分支A代码完全一致且是最新代码)。
步骤7:
基于本地分支A创建本地分支B(此时本地分支B、本地分支A和远程分支A代码完全一致)。
步骤8:
在本地分支B改动代码、提交并推至(commit&push)远程分支B(本次提交也是只显示之前改动的那8个文件)。
步骤9:
在gitlab上发起合并请求,合并远程分支B到远程分支A(此时就是正常的commits数和changes数了),如果提交记录正常则同意合并请求:
至此问题已经解决!
拓展:Git的cherry pick神操作
我想问一下各位小伙伴在步骤8中,你们是如何在本地分支B改动代码的呢?我相信大家都能想到的做法应该是:先把步骤3中涉及到的所有改动代码先备份一下,然后在步骤8时,根据备份代码去改动所有对应的代码。
但是我想说的是:这种想法确实是简单,但是操作起来太浪费时间、太笨拙了。所以这里我要介绍一种最快速最简洁最方便的方式:GIt的神操作——cherry pick:
cherry pick的作用:
可以将某个特定的提交(commit)记录的代码改动更新到当前分支。
cherry pick(筛选合并)和 merge(合并)的区别:
两者都能用于合并代码;但是merge是将分支1的所有代码合并到分支2,操作对象是分支1、分支2;而cherry pick是将某次commit提交的代码合并到当前分支,操作对象是commit记录、当前分支。
相信部分悟性高的伙伴在看到这里时已经知道接下来要做什么了。
接下来我们就可以在git历史提交记录中找到步骤3的那次提交记录,然后通过cherry pick操作将那次commit记录的代码改动全部更新到本地分支B,这样就能完美实现步骤8的“改动代码”工作了,具体操作如下:
首先切换到本地分支B,然后在IDEA开发工具的 Git - Log窗口 中,找到步骤3的那次提交记录,右键点击 Cherry-Pick即可。
这样就能直接将步骤3改动的代码完全更新到本地分支B了!!!
我愿称之为git神操作。
拓展:步骤4的合并请求被同意后该如何解决?
由于上面提到的操作步骤都有一个前提条件,那就是:
在步骤4的合并请求同意之前,我们就已经通过commits数和changes数异常,发现了问题!
所以估计有人会问,假如步骤4的合并请求已经被同意了(即远程分支A的代码已经是有问题的代码了)该怎么办呢?
考虑到这种情况的存在,我又写了一篇新的文章来详细分析问题并提供解决方法,感兴趣的小伙伴可以自行前往查看,文章连接:
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)