前言
我们在开发中,经常是很多人开发同一份代码,早期没有git工具的时候那可真是噩梦,要复制来复制去,不止繁琐,还容易出错,所以后来涌现了各种代码工具,Svn,Git等等,而Git是现在比较流行的
他支持多分支代码开发,可以多人同时进行,可谓是方便很多,但是,多分支开发同时也存在一个问题,那就是合并冲突问题,本篇文章重点在于说明多分支合并问题,而不是一篇关于如何介绍解决冲突的问题,下面就说一下存在的问题
注:如果对于分支不懂的可以参考我的另一篇文章:分支基本操作
多分支开发存在问题
比如你现在有一个git仓库代码,默认分支为master(真实环境中还有sit,qa,dev等,这里不讨论,为了方便说明只讨论master分支),如果只有一个人开发那是不会有任何问题,现在来看以下这么个问题:
master仓库中只有一个zxc.txt文件,内容如下
mulitDevelop为仓库名字,你会看到有一个.git的隐藏文件夹,假设现在有2个人需要对这个项目进行开发,如下:
开发者A ,他拉取了一个分支 develop-a 的分支
开发者B, 他拉取了一个分支 develop-b 的分支
现在,开发者A在zxc.txt文件中第三行添加内容,如下
接着,开发者在文件中添加内容,如下:
然后,这个时候master先把开发者a的内容合并过去,此时肯定是没问题的,命令如下
先切换到master分支 : git checkout master
然后把开发者a的代码进行合并: git merge develop-a
合并完master的文件内容如下:
可以看到master现在代码已经有了开发者a的内容了,这个时候还是正常操作,但是如果现在master要合并develop-b的代码那会怎样?没错,他就会产生冲突,因为zxc.txt文件中第三行出现了不一样的内容,git无法确定要使用谁的,这也是我们开发过程中经常会遇到的问题,执行的命令如下
先切换到master分支 : git checkout master
然后把开发者a的代码进行合并: git merge develop-b
执行后的内容如下:
这便是出现了冲突的问题,如果看不懂的这些标记的请自行寻找百度git冲突打的标记,现在问题就已经出来了,开发者a的代码先被合并到master,此时是正常的,开发者b的代码被合并到masterb的时候会产生冲突,如下所述,接下来我们就来说下这个问题解决至少有的方案
注:开发过程中合并的时候是合并远程的,如果有冲突在合并的时候操作端会有提示,然后我们再去解决,这里是为了方便,所以直接在本地让你看到了效果
至少有的解决方案
解决方案一
当提前发现有冲突的时候,我们可以站在develop-b的角度上先合并master的代码,然后自己解决再提交,如下是在develop-b的操作
然后进行解决冲突,解决后如下:
这个时候再回到master进行合并develop-b就不会冲突了,如下是master合并前后的代码
至此,解决方案一就完成了
注:可能有人会说,这不跟master合并develop-b代码一样吗,也确实,不过我上面就说了,真正的开发中可能是通过界面远程进行合并的,如果有冲突你是已经知道了,所以你可以这么操作
存在的问题
不知道你发现没有,这种方式其实是存在问题的,什么问题呢?就是develop-b的分支代码受到了污染,在刚开始从master创建develop-b分支的时候当时是没有develop-a的代码,也就是没有下面这个内容:hello i am develop-a
这让devleop-b分支的代码变得不纯正了,对于以后的后续操作可能会有问题,如果你能接受倒也没事,不能的话就需要其他的方式处理,还有这种操作可能会导致git分支走向图会有点奇怪,普通分支合并了master分支的代码等问题。。。。
解决方案二
为了解决上面的问题,一个简单的方式是直接站在master合并develop-b代码,然后解决就行,这样一来就不会污染了develop-b分支代码了,是不是很简单,但是有时可能由于其他问题,你没办法这么做,那你还能怎么做呢?就需要用其他的解决方案了,下面进行介绍
解决方案三(推荐)
rebase使用方法请参考: https://www.jianshu.com/p/a4478c97f1b7,一篇写的不错的
前面的操作逻辑都是一样的,关键还是回到master合并develop-b会冲突的那个步骤上,假设现在我们已经知道了master合并develop-b会冲突,执行以下的命令
git checkout master ##切换到master分支
git pull orgin master ##拉取远程master分支最新代码到本地
我上面的例子都是跟远程无关的,所以其实并没有这个步骤
git checkout develop-b # 切换到develop-b分支
git rebase -i master #然后这时候就会有冲突了,解决冲突之后往下执行。ps:我用的是 SourceTree,冲突文件会被标注出来,手动解决冲突就行
git rebase --continue #是两个横杠,中间无空格,横杠跟“ continue” 之间也无空格
作者:柴小斌
链接:https://www.jianshu.com/p/5ac65cc387fa
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
git rebase -i master rebase master的代码
然后进行解决,再提交,如下
然后再切换到master合并develop-b分支就行了
疑问
你一定会有的疑问用这种方式develop-b不是一样被污染了吗,有啥意义,其实不是的,用rebase只会合并有冲突的代码,merge是合并了全部代码,也就是说,如果代码没有冲突,那你在develop-b执行git rebase -i master的时候(确实还是会污染分支,只是让提交历史看起来好看点,我也是边写博客边验证才发现的,,,我的锅,如果没兴趣的可以不需要往下看了....),会展示如下:
现在develop-a添加的代码如下:
develop-b的代码如下:
由于分支develop-a核develop-b添加的内容在文件里并没有冲突,那么此时先合并develop-a再合并develop-b其实是不会有问题的,步骤还是一样的,我还是在master上合并develop-a的代码,如下
此时如果直接再合并develop-b,肯定也是没问题的,因为并不冲突,我这里就不试了,有空的可以试下,这里我主要是试一下此时如果在develop-b会发生啥:git rebase -i master , 如下:
可见,最终还是会污染代码,那么rebase有什么用呢,只是会让提交历史看起来正常点.....,中文称为变基,我也是边写博客边学习,看来rebase并不能解决分支污染的问题,,大意了了,那目前就只有第二种方式可以了,如果有其他方式我再补上来....