我打算翻译《Become a git guru》系列git教程文章,欢迎有兴趣翻译这系列教程的朋友加入我一起完成翻译。
译者注:这篇文章很好的介绍了如何使用合并申请功能来保证项目质量可靠性和帮助团队成员交流成长。文章使用了Bitbucket(一个类似github的代码共享网站)作为远程代码管理工具,国内开发者使用github居多,公司内部可能使用gitlab更多,不过译者认为他们使用方式大同小异,原理更是相通,所以还是决定原文翻译。如果有时间我会针对gitlab单独写一份教程。
使用Bitbucket的合并申请功能让开发者之间合作变的非常的easy。你可以使用Bitbucket提供的非常nice的网页管理界面让大家探讨这些修改,然后再合并代码到正式项目。
你可以仅仅使用合并申请功能来通知团队成员你已经完成了可一个功能开发。当开发者完成他们开发的功能后,他(她)可以登陆Bitbucket,然后发起合并申请。这可以让被通知到人去review代码并合并这些代码到master分支(译者注:应该是指团队主开发分支)。不过合并申请功能可不止发送通知这么简单——它可以用来作为讨论提出申请的功能的专用论坛。如果代码有任何问题,团队成员们可以提出反馈,甚至推送(push)提交来小小的修改代码。合并申请功能可以追踪这些事情。
跟其他团队合作模型相比,这个分享代码提交的方案使得开发流程更加顺畅。SVN和Git都可以通过简单脚本配置就可以自动发送邮件。然而当需要讨论修改时,如果依赖邮件,那将邮件满天飞,会让事情变的混乱,再加后续的修改提交,就更加恐怖了。合并申请把所有这些事情集合在一个web界面上。你仅仅需要请求另外一个开发者(比如,项目维护者)来从你的仓库拉取代码合并进他的仓库就可以完成一个合并申请。这意味着你发起合并申请需要提供4个信息:源仓库、源分支、目标仓库、目标分支。
Bitbucket为这四个值提供了合理的默认值。然而,根据不同项目不同合作开发流,你的团队可能需要设置不同的默认值。上面的图表展示如何请求从一个功能分支合并到正式的主干分支(master)。但合并申请的功能比这要多的多。
如何进行
合并申请可以被运用在功能分支工作流(Feature Branch Workflow),
(GitFlow工作流(Gitflow Workflow),Forking工作流(forking WorkFlow)。但是合并申请需要在两个不同分支或者不同仓库之间进行,所以它不适用于标准意义上的集中式工作流(Centralized Workflow)。在不同开发工作流上使用合并申请略有不同,不过基本流程是一样的:
- 开发者在本地仓库创建一个功能开发专用的分支。
- 开发者将分支推送到远程仓库
- 开发者发起合并申请
- 团队成员review代码,展开讨论或者修改他们。
- 项目维护者合并该分支到正式仓库然后关闭合并申请。
后面的内容我们来聊聊合并申请是如何助力不同的合作开发工作流的。
功能分支工作流中的合并申请
功能分支工作流主要用于在同一项目中管理团队合作开发的,开发者们为每个开发的的功能创建分支。但是在代码合并进主干分支前,开发者需要发起合并申请,让大家讨论他开发的功能,这些完成之后才能合并到正式代码里。
由于在功能分支工作流中只有一个公有仓库,因此合并申请的源仓库和目标仓库是一样的,一般来说开发者指定他的功能分支作为源分支,主干分支作为目标分支。
项目管理者在收到合并申请后,会去查看提交的代码,如果没有问题就会合并代码到主干分支并关闭申请,但是如果在修改的代码中发现问题,他可以在合并申请界面进行反馈,对应的修改提交会显示在评论的右边。
发起一个没有开发完成的功能也是允许的。比如当一个开发者在开发某个需求时遇到困难,他们可以发起包含需要提交的代码然后发起申请,其他开发者可以在合并申请界面提供建议,或者直接动手帮忙解决问题并提交修改。
GitFlow工作流中的合并申请
Gitflow工作流类似工作分支工作流,但是在项目发布周期中严格精确地定义了一个分支模型,在GitFlow工作流中加入合并申请可以让开发者围绕他们正在工作的发布分支或者维护分支进行讨论。
Gitflow工作流中合并申请的使用跟之前一样:一个开发者发起一个需要被review的功能、发布、热修复代码的合并申请,团队其他成员通过Bitbucket收到通知。功能开发通常合并进develop分支,然后发布分支和热修复分支通畅合并进develop和master两个分支。合并申请可以在所有这些合并中用到。
Forking工作流中的合并申请
在Forking工作流中,开发者将代码先推送到自己的仓库而不是公有仓库。然后,他可以发起合并申请请求项目管理者review代码。合并申请的通知功能在这个时候就特别有用,因为这可能是当开发者向项目管理者的仓库提交代码时项目管理者知道有新代码提交的唯一方式。
由于开发者有自己的公有仓库,当他们提起合并申请时候源仓库是和目标仓库不同,目标仓库是正式仓库,目标分支主干分支。
合并申请也可以运用于正式项目之外,例如,当你和队友合作开发一个功能时,这个时候我们发起合并申请可以使用对方仓库作为我们的目标仓库而不是正式项目,我们可以约定同一个功能名称作为源分支和目标分支。
你们可以在合并申请界面讨论和开发功能,当你们开发完后,你们中可以由一个人向正式项目发起合并申请。合并申请的这种灵活性在forking工作流中尤其有用。
举个例子
下面的例子说明了如何在forking工作流中使用合并申请。对小团队以为开源项目贡献代码的个人开发者一样有效。
在这个例子中,小红(Mary)是一个开发者,小明(John)是项目管理者。他们都有自己的公有仓库,并且小明拥有正式仓库。
小红拷贝(fork)正式仓库
为了给小明的项目贡献代码,小红需要先拷贝小明的仓库到自己的公有仓库,她可以登录bitbucket,找到小明的仓库然后点击fork按钮即可。
不一小会儿她就拥有了这个项目的一份拷贝了,注意看看姓名和描述是否改变。
小红克隆(clone)她的公有仓库
然后,小红需要克隆她刚才拷贝(fork)的仓库。这样子她在自己的设备上就有了可以开发的仓库了。我们通过命令实现:
git clone https://user@bitbucket.org/user/repo.git
时刻记住git clone会自动创建一个origin用来指向自己远程拷贝的分支。
小红开发一个新功能
在小红开发新功能时,小红需要创建一个分支用于开发功能。这个分支将是她发起合并申请时的源分支。
git checkout -b some-feature
#Edit some codegit
commit -a -m "Add first draft of some feature"
开发一个功能小红可能会有很多个提交(commit)。如果分支历史非常混乱她可以使用交互式合并(interactive rebase)来去除或者压缩(squash)无用的提交。在大型项目中,清理分支历史让项目的维护者更容易在合并申请里知道你的修改里做了什么事情。
小红将她开发的功能推送(push)到她的公有仓库
在她开发完功能后,小红将功能分支推送到她的远程仓库(不是别人维护的正式仓库,是她fork的仓库),她可以使用这个命令:
git push origin some-branch
这个让她的修改就在公有仓库里,这样其项目维护者或者其他开发者可以获取到她的修改。
小红创建合并申请
在代码push完成后,小红登录Bitbucket,找到她fork的项目,然后点击右上角的Pull request按钮发起合并申请。弹出表达默认设置小红的仓库为源仓库,病要求她设置源分支、目标仓库和目标分枝。
小红需要合并她的代码到正式项目,所以她设置她的分支为源分支,目标仓库为小明的共有正式仓库,目标分枝为主干分支master。她还需要输入标题和描述她的修改,然后在Reviewers 输入框选择能够同意她的修改的人(包括小明)。
在她创建合并申请后,小明就会通过邮件或者订阅收到通知。
小明评审(review)代码
小明可以在他的仓库通过点击标签 Pull request 来查看所有人的合并申请。点击小红的申请,他将看到小红的申请描述,她分支的提交历史,以及该分支代码包含的修改的差异对比(diff)。
如果他认为功能可以合并进正式项目,他只需要点击Merge按钮同意合并申请,然后就会合并小红的功能代码到他的主干分支master。
但是,假如小明在小红的代码里发现了小bug,需要小红在合并前修改代码,他可以在合并申请恢复,可以在大输入框里做一个整体评论,也可以选择一个具体的提交来评论。
小红添加随后的补充提交
如果小红对收到的反馈有任何问题,她可以在合并申请里恢复,类似论坛一样。为了修复错误,小红添加一个新的提交到她的分支,再推送到她的仓库,就像她之前做的那样。她的合并申请自然加到了原来的合并申请里了。然后小明就可以在他评论的地方再次评审。
小明同意合并
最后,小明同意这些修改,合并功能到master主干分支,关闭合并申请。这样功能代码就正式集成到项目了。所有这个项目的贡献者就可以使用标准的git pull拉取这些修改到他们本地的仓库了。
总结
现在你已经掌握了所有技能和工具来帮助你使用合并申请。记住,合并申请不是其他所有基于Git的工作流(Git-based collaboration workflows)的替代者,而是你和其他团队成员合作开发的有利补充。