Git 以及基于 Git 的各代码开发协作平台,比如 Github, Gitlab, Bitbucket, TFS Git 等正逐渐成为首选的代码版本管理工具,而基于 Git 的基本开发流程则是开发者创建个人的私有分支并在个人的私有分支上提交代码,代码完成后创建合并请求(pull/merge request)到主分支让相关人员做代码评审,评审通过后将合并请求(pull/merge request)合并到主分支上。
用一句话总结就是:你收到一个任务后,在团队分支的基础上创建一个个人分支并在这个分支上开发,完成后将代码推送到远程,并发起申请合并请求,即将个人分支合并到团队分支上,由团队负责人审核该分支的代码并决定是否合并到团队分支上。
从上述总结我们可以看出,合并请求的作用之一是代码审查,团队负责人对每个项目参与者的代码进行初步审查后,再决定合并与否,一定程度上可以减少 bug
的数量,尤其是审查新手或者说不太懂 git
的程序员的代码。
上面只是陈述性地说明了什么是合并请求以及合并请求的作用,下面将通过菜鸟犯过的错误来直观地感受合并请求的重要性。
菜鸟犯的两个错误
菜鸟小明和大师老白共同开发一个项目,一人负责项目的一半。小明菜,先一步开发,完成一个模块后就把代码推送到 dev
分支上。老白经验丰富,拉取、开发、推送自然不在话下。到这里,一切都还正常,因为是小明先推送代码。第二天小明从 dev
分支上拉取代码时,问题就出现了。因为小明负责模块的路由和老白负责模块的路由写在同一个文件中,所以小明在第二次拉取代码的时候,远程的路由文件和本地的路由文件起了冲突,需要手动合并。菜鸟小明在解决冲突时,不太懂 Accept Current Change
和 Accept Incoming Change
的含义,就凭感觉点了一个选项(事实证明是错的),完成一天的开发后就把代码推送到了 dev
分支上。而这时菜鸟小明还没有意识到自己犯了错——把老白写的路由都删了。这是菜鸟小明犯的第一个错误。
菜鸟小明犯的第二个错误就是把另外一个模块的同名文件改了。小明负责的某个模块的某个功能与项目中另外一个模块的功能非常类似,图省事,就创建了一个类似的文件,取了一样的文件名。小明习惯用 ctrl + g
这个快捷键跳转文件,有可能是累了,有可能是午休没睡醒加上那段时间状态不太好,恍惚间误改了另一个模块的文件,导致出现了很严重的问题。
相信你可以感受到,如果让菜鸟小明去合并团队的代码,问题将会是无穷无尽的。事实上,老白发现小明删除了他写的路由后就让小明提交合并请求而非直接把代码推送到 dev
分支上。菜鸟小明听到“合并请求”时一头雾水,虽然他在网上找到了一篇非常详细地介绍“合并请求”的博客——保姆级教程 | Merge Request 分支合并请求,但是实际操作起来还是差点意思,最后还是在老白的帮助下,菜鸟小明才搞明白了合并请求的流程。
流程
以在一个项目中增加一个新功能 A 为例:
- 切换到本地的
dev
分支,并将远程的dev
分支拉取到本地; - 在本地
dev
分支上新建一个分支feat_A
,并切换到该分支上; - 在
feat_A
分支上进行开发; - 进行开发并提交你的代码;
- 将
feat_A
分支推送到远程; - 找到并点击
merge_request
按钮,选择好对应的参数,点击合并; - 等待审核结果,如果审核通过,就将远程和本地的
feat_A
分支删除; - 如果新的任务来了,就重复以上步骤。
4、5 步骤在实际的开发中可能会重复执行,直到一个完整的功能开发完成。
详情参考 保姆级教程 | Merge Request 分支合并请求
可能出现的问题
远程仓库的代码和本地仓库的代码出现冲突,使用 git pull origin <remote branch>
拉取远程代码时,会出现一个多余的 merge commit
。
如果多人多次如此操作,那么提交记录就会出现很多条这种自动生成的 merge commit
,非常难看。
而使用 git pull --rebase <remote branch>
这个命令行,就可以避免生成多余的 merge commit
,使提交记录更加干净清爽。
流程优化——合并提交
假如需要在项目中新增一个功能 A,这个功能非常大,需要四五天才能完成。在接到这个任务后,正常情况下,执行 1、2、3 步骤,但是这个功能一天开发不完,在下班前会提交一次当天的代码,然后推送到远程,循环往复,直到最后一天开发完 A 功能,才把分支合并到团队的分支上。
这样做也没什么大问题,但是一个功能有四五次提交,如果功能更大更难,就会出现更多次的提交,不方便 code review。
更好的做法是合并提交:将开发功能 A 的所有提交合并为一个提交,随后合并到团队开发的分支上。
可以使用 git rebase -i
命令行来合并多个提交,详情参考 git 合并多次提交
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。