拉取请求是Bitbucket的一个特性(经调查,Gitlab、Github都支持这个特性),可以让开发人员的协作更加容易,他们提供了一个友好的网页界面让开发者在集成代码到正式库之前对其进行讨论。
Bibucket
简单来说,“拉取请求”是一个通知机制,让开发人员提醒团队成员一个特性已经开发完成了。当一个特性开发完成后,开发人员在Bitbucket上创建一个“拉取请求”,其他人就知道需要对代码进行评审,并合并进master分支。
但是,“拉取请求”不仅仅是一个通知,它是一个专门讨论特性的论坛,如果提交的变更有任何问题的话,团队成员在“拉取请求”里面张贴反馈,甚至可以推送一些提交记录对特性进行调整,所有这些活动在“拉取请求”里都能跟踪得到。
跟其它协作模型相比,这个形式的提交记录共享方案使工作流程更加简化,SVN和Git都能够自动地发送通知电子邮件,但是这个方式很不利于进行变更讨论,尤其是邮件无法自动包含他人的提交记录。而“拉取请求”将这些必要的功能整合进界面友好的Bitbucket代码库中,使用起来就非常便捷。
“拉取请求”的结构
当开发人员创建一个“拉取请求”时,其实也正在请求其他开发人员(也许是项目运维人员)从你的代码库里拉取分支到他们自己的库里,要达到这个目的,需要提出请求的人提供四类信息:源代码库、源分支、目标代码库、目标分支。
Bitbucket里提供了明显的功能供使用者选取这些值,当然,至于具体选那些值就因团队的工作流程而异了。上图显示了一个请求合并分支到正式master分支的“拉取请求”,其实是用“拉取请求”的方式还有很多。
它是如何工作的
“拉取请求”能够为特性分支流程、Gitflow流程、交叉型流程提供助力,不过它同时需要两个不同的分支或两个不同的代码库,因此并不适合中心式流程。在前三个流程里面使用“拉取请求”的方式有一些细微差异,不过主要流程是一样的:
- 开发人员在本地代码库里创建特性专用的分支
- 开发人员推送分支到公共的Bitbucket(Github、Gitlab)仓库
- 开发人员在Bitbucket(Github、Gitlab)里发起一个“拉取请求”
- 团队其他成员讨论、评审、修改代码
- 项目运维人员将特性代码合并到正式库兵关闭“拉取请求”
本节其余的部分主要讲“拉取请求”在不同的流程里如何产生影响。
特性分支流程里的“拉取请求”
特性分支流程使用共享的Bitbucket库进行协同管理,开发人员用独立的分支创建特性,在合并特性到master之前,开发人员应该开启一个“拉取请求”围绕特性进行讨论。
特性分支流程只有一个公共库,“拉取请求”得目的库和源库就是同一个库了,开发人员只需要设定特性分支为源分支、master分支为目标分支即可。
项目运维人员收到“拉取请求”后必须确定下一步动作,如果特性开发完备,可以简单地和并进master并关闭“拉取请求”;如果有一些一问题,可以在“拉取请求”回复,回复的内容紧邻相对应的提交记录。
即使特性开发工作还没有完成,仍然可以创建“拉取请求”。比如当开发人员在具体需求上碰到问题时,可以创建包含工作半成品的“拉取请求”,其它开发人员能够在这个“拉取请求”内提供自己的建议,或者直接提交代码进行问题修复。
Gitflow流程里的“拉取请求”
Gitflow工作流程跟特性分支流程很相似,只不过围绕项目发布定义了严格的分支模型,在Gitflow使用“拉取请求”让开发人员能够针对发布分支或维护分支进行高效的讨论。
Gitflow里“拉取请求”的构成跟其它流程里的一模一样:当分支、发布、热修复分支需要被评审时开发人员创建之,其他成员就能被Bitbucket通知到。
交叉型流程里的“拉取请求”
在交叉型流程里,开发人员将开发完成的特性推送到自己的公共库里,然后创建一个“拉取请求”通知项目运维人员准备进行评审。
工作流程里“拉取请求”的通知非常有用,因为运维人员并不知道何时有人向Bitbucket代码库里提交了代码。
每个开发人员都有自己的公共库,“拉取请求”得源代码库和目标代码库是不一样的,源代码库是开发者自己的公共库、源分支是开发者开发时创建的特性分支,而目标代码库和目标分支是正式项目的代码库和master分支。
“拉取请求”也被用于跟正式项目之外的开发人员协同开发,比如,如果一个开发人员正在和某个团队成员共同工作在某一特性上,他们可以通过“拉取请求”将团员的个人公共库作为目标代码库。
这两个工程师可以在这个“拉取请求”内讨论和开发本特性,开发完成后,其中一人向正式项目“拉取请求”,“拉取请求”如此灵活的特性使其成为交叉型工作流程里非常有用的工具。
示例
下面的例子演示了“拉取请求”在交叉型工作流程里的用法,“拉取请求”无论在小团队还是大型、开源项目里都是适用的
本示例中,Mary是一个开发人员,John是项目运维人员,他们都有自己的个人公共BitBucket代码库,John还有项目的正式库。
Mary复制了正式代码库
Mary首先从John的Bitbucket仓库里分出一个拷贝,她登入Bitbucket,导航到John的代码库,点击“Fork”按钮完成本操作:
填写一些基本的库信息后,她就拥有了自己的服务器端项目拷贝。
Mary克隆她自己的Bitbucket代码库
然后,Mary需要从她分叉出来的代码库克隆,以让自己拥有项目的本地拷贝,运行如下命令:
git clone https://user@bitbucket.org/user/repo.git
注意,git clone自动创建了一个origin远端连接指向Mary分支出来的公共代码库。
Mary开发了一个新特性
写代码之前,Mary需要创建一个新特性分支,这个分支将会是“拉取请求”的源分支。
git checkout -b some-feature
# Edit some code
git commit -a -m "Add first draft of some feature"
Mary提交了许多记录来完成这个特性,如果她觉得特性的提交历史比她想象的杂乱,可以使用rebase功能移除一些不必要的提交记录。对大型项目来说,清除特性的提交历史让运维人员能够更加轻易地看到在“拉取请求”里发生的事情。
Mary想Bitbucket仓库推送分支
特性开发完成后,Mary推送特性分支到自己的Bitbucket仓库(不是正式库):
git push origin some-branch
这样她所做的变更就对项目运维人员(或其他协作者)可见了。
Mary创建了一个“拉取请求”###
在Bitbucket里保存了Mary的特性分支后,她能够在自己的Bitbucket里得代码库创建“拉取请求”,Bitbucket自动把Mary的代码库设为源库,需要Mary自己设置源分支、目标库和目标分支。
Mary想要合并自己的特性到主代码库,她设置了自己的特性分支为源分支,设置John的公共库位目标库,目标库的master分支为目标分支,同时Mary需要设置“拉取请求”的名称和可能的说明,如果在运维人员之外需要有其他人批准这些代码,她也可以在评审者字段里输入这些人员。
Mary创建了“拉取请求”后,对应的通知将会通过Bitbucket消息机制和邮件通知给John。
John查看“拉取请求”
John通过自己Bitbucket账户里的“拉取请求”标签页访问“拉取请求”,点击Mary的“拉取请求”能看到“拉取请求”的详细信息、特性的提交历史和其包含的所有变更。
如果他觉得特性已经就绪可以合并到项目中,他要做的事情只是单击合并按钮批准这次“拉取请求”,并把Mary的特性合并入master分支中。
但是,如果John发现了一个bug,需要Mary修复,他也可以提交一个注释到“拉取请求”里,后者选择一个具体的提交记录进行注释。
Mary添加了后续的提交记录
Mary对John的有疑问的话,她可以在“拉取请求”做出响应,把其作为特性分支的讨论论坛。
为了修正错误,Mary添加了另外一个提交记录到特性分支并推送到自己的Bitbucket仓库,这次提交被自动加入到刚刚的“拉取请求”中,John能够在紧邻自己原来注释的位置再次复查变更。
John接受“拉取请求”
最后,John接受了变更,把特性分支合并到master中,并关闭了这个“拉取请求”。现在本特性被集成到了项目中,其他工程师可以使用git pull将之拉取到自己的本地代码库中。
何去何从
现在我们对“拉取请求”有了更深入的了解,它不是Git工作流程的替代品,而是对它们的支撑,提供了团队高效写作的场合和工具。
注意:本文归作者所有,未经作者允许,不得转载