如何避免80%的GIT提交冲突

1,499 阅读4分钟

...以及让其他的冲突变得无关紧要

你是否很害怕每次提交产生的代码冲突,或者你身边就有这样的人? 这篇文章会分享一些用于更好地合并分支的方法,这样就无需再对合并分支时产生的冲突而担心了。

Git 的工作模式就像一个三明治

GIT会将每一次提交的代码放在已经存在的代码的顶端,就好像在一个三明治的顶上再加一层肉或者是奶酪。只不过这一堆代码永远不会因为太高而坍塌。

就像三明治一样,代码的提交顺序很重要。你总不会想把两片面包都放在三明治的最顶端,下面才是一把生菜,紧接着是肉和奶酪吧。当然如果你愿意这么吃,那也没关系,我不会说三道四。但是代码提交的时间顺序,是非常要紧的事情。Git merge 命令和 rebase 命令就是用来管理在代码库中使用什么顺序来叠加代码片段的。

当合并请求(merge request)发生冲突时,就好像我们不知道哪一层应该覆盖哪一层,是应该萨拉米肉肠覆盖奶酪片,还是奶酪片覆盖酱汁肉丸。通常来说GIT自身的机制会自动去判断代码片段的叠加顺序,但当代码片段的覆盖情况比较复杂时,GIT也无从自动判断覆盖顺序,它会请求你的帮助(产生冲突,提醒提交者手动处理冲突)。每当遇到这种情况时,都会令人生厌,但处理冲突总好过代码被GIT自作主张的胡乱合并一通。

免责声明

准确来说,git merge命令不仅仅是把代码变更叠加到代码仓库中去那么简单。GIT 会在代码仓库中找到两个分支中最后一次共同的提交(last common commit revision),然后从那一点开始合并两个分支的改动。但是如果参照如下方法,就不需要再担心合并代码产生的冲突了。因为它能够保证最后一次共同commit总是在目标分支的最顶端。

只有两种场合

大多数情况下,要么是把工作分支合并到公用分支上去,要么把公用分支的改变合并到工作分支上来。

避免产生合并冲突的技巧,就在于要搞清楚当前这次合并请求属于上面描述的哪种场景。

merge工作分支到公用分支

当你在公用分支上(并且你已经pull过远端的最新代码,并更新了本地分支),然后执行

git merge my-branch

rebase公用分支到工作分支

当你在工作分支上,然后执行

git rebase master

这个命令执行过程中会做如下几件事情:先把你在工作分支上做的变更拿开,然后把公用分支上的变更放进工作分支,最终再把第一步拿开的变更放回最顶端。就好像当你完成一个三明治后,还想再添加一层牛肉片,于是拿开顶端的面包,把牛肉片放在顶层,再把刚才拿开的面包放在牛肉片上面。

步骤

在代码库中添加代码变更而不产生冲突,需要遵守如下步骤。

首先,必须保证公用分支的本地版本是最新的。

​
git fetch --prune
​
git pull origin master
​

其次,使用rebase命令,把公用分支rebase到工作分支。

git pull origin master --rebase 
​
# or
​
git rebase master

代码冲突只会在这个步骤中产生,且仅当工作分支上一次rebase公用分支之后到此次rebase之前,其他人向公用分支提交了与工作分支相同的代码块变更,所以这种情况下的冲突也非常容易修正。

(需要注意的是,本地工作分支需要及时与公用分支保持一致,如果工作分支与公用分支的变更数都很多,rebase会将工作分支与公用分支的每一次commit依次进行比较,并尝试合并,这时可能产生的冲突就非常多了。所以在工作中保证工作分支及时更新公用分支是一个非常良好的习惯,会大大减少代码冲突)

因此最好经常在工作分支上做如上两步操作,至少一天一次。

最终,无论什么时候你想把工作分支合并到公用分支上,请保证在提交合并前已经完成上面这两个步骤。如此即可保证工作分支的提交永远超前于公用分支的顶端,GIT就可以轻而易举地将分支合并到公用分支之上。