使用git和github进行协同开发流程

做者:戴嘉华html

转载请注明出处,保留原文连接和做者信息git


目录

  • 前言
  • 仓库(Repository)

    • 源仓库
    • 开发者仓库
  • 分支(Branch)

    • 永久性分支
    • 暂时性分支
  • 工做流(workflow)
  • 总结
  • 参考资料

前言

(本文假设各位已经对基本git的基本概念、操做有必定的理解,如无相关git知识,能够参考Pro Git这本书进行相关的学习和练习)github

不少项目开发都会采用git这一优秀的分布式版本管理工具进行项目版本管理,使用github开源平台做为代码仓库托管平台。因为git的使用很是灵活,在实践当中衍生了不少种不一样的工做流程,不一样的项目、不一样的团队会有不一样的协做方式。分布式

本文将介绍一种前人已经在各类大小项目中通过千锤百炼总结出来的一种比较成功的git工做流,这种工做流已经被成功用于许多团队开发当中。掌握git,掌握这种工做流,对你们之后的学习、开发工做大有好处。工具

先上一张图吓你们一下:post

workflow

上面一张图展现了一种使用git进行项目协同开发的模式,接下来会进行详细介绍。学习

仓库(Repository)

在项目的开始到结束,咱们会有两种仓库。一种是源仓库(origin),一种是开发者仓库。上图中的每一个矩形都表示一个仓库,正中间的是咱们的源仓库,而其余围绕着源仓库的则是开发者仓库。测试

源仓库

在项目的开始,项目的发起者构建起一个项目的最原始的仓库,咱们把它称为origin,例如咱们的PingHackers网站,origin就是这个PingHackers/blog了。源仓库的有两个做用:网站

  1. 汇总参与该项目的各个开发者的代码
  2. 存放趋于稳定和可发布的代码

源仓库应该是受保护的,开发者不该该直接对其进行开发工做。只有项目管理者(一般是项目发起人)能对其进行较高权限的操做。编码

开发者仓库

上面说过,任何开发者都不会对源仓库进行直接的操做,源仓库创建之后,每一个开发者须要作的事情就是把源仓库的“复制”一份,做为本身平常开发的仓库。这个复制,也就是github上面的fork

每一个开发者所fork的仓库是彻底独立的,互不干扰,甚至与源仓库都无关。每一个开发者仓库至关于一个源仓库实体的影像,开发者在这个影像中进行编码,提交到本身的仓库中,这样就能够轻易地实现团队成员之间的并行开发工做。而开发工做完成之后,开发者能够向源仓库发送pull request,请求管理员把本身的代码合并到源仓库中,这样就实现了分布式开发工做,和最后的集中式的管理。

分支(Branch)

分支是git中很是重要的一个概念,也是git这一个工具中的大杀器,必杀技。在其余集中式版本管理工具(SVN/CVS)把分支定位为高级技巧,而在git中,分支操做则是每一个开发人员平常工做流。利用git的分支,能够很是方便地进行开发和测试,若是使用git没有让你感到轻松和愉悦,那是由于你尚未学会使用分支。不把分支用出一点翔来,不要轻易跟别人说你用过git。

在文章开头的那张图中,每个矩形内部纷繁的枝蔓即是git的分支模型。能够看出,每一个开发者的仓库都有本身的分支路线,而这些分支路线会经过代码汇总映射到源仓库中去。

咱们为git定下一种分支模型,在这种模型中,分支有两类,五种

  • 永久性分支

    • master branch:主分支
    • develop branch:开发分支
  • 临时性分支

    • feature branch:功能分支
    • release branch:预发布分支
    • hotfix branch:bug修复分支

永久性分支

永久性分支是寿命无限的分支,存在于整个项目的开始、开发、迭代、终止过程当中。永久性分支只有两个masterdevelop

master:主分支从项目一开始便存在,它用于存放通过测试,已经彻底稳定代码;在项目开发之后的任什么时候刻当中,master存放的代码应该是可做为产品供用户使用的代码。因此,应该随时保持master仓库代码的清洁和稳定,确保入库以前是经过彻底测试和代码reivew的。master分支是全部分支中最不活跃的,大概每月或每两个月更新一次,每一次master更新的时候都应该用git打上tag,说明你的产品有新版本发布了。

develop:开发分支,一开始从master分支中分离出来,用于开发者存放基本稳定代码。以前说过,每一个开发者的仓库至关于源仓库的一个镜像,每一个开发者本身的仓库上也有masterdevelop。开发者把功能作好之后,是存放到本身的develop中,当测试完之后,能够向管理者发起一个pull request,请求把本身仓库的develop分支合并到源仓库的develop中。

全部开发者开发好的功能会在源仓库的develop分支中进行汇总,当develop中的代码通过不断的测试,已经逐渐趋于稳定了,接近产品目标了。这时候,咱们就能够把develop分支合并到master分支中,发布一个新版本。因此,一个产品不断完善和发布过程就正以下图:

master & develop

注意,任何人不该该向master直接进行无心义的合并、提交操做。正常状况下,master只应该接受develop的合并,也就是说,master全部代码更新应该源于合并develop的代码。

暂时性分支

暂时性分支和永久性分支不一样,暂时性分支在开发过程当中是必定会被删除的。全部暂时性分支,通常源于develop,最终也必定会回归合并到develop

feature:功能性分支,是用于开发项目的功能的分支,是开发者主要战斗阵地。开发者在本地仓库从develop分支分出功能分支,在该分支上进行功能的开发,开发完成之后再合并到develop分支上,这时候功能性分支已经完成任务,能够删除。功能性分支的命名通常为feature-*,*为须要开发的功能的名称。

feature branch

举一个例子,假设我是一名PingHackers网站的开发者,已经把源仓库fork了,而且clone到了本地。如今要开发PingHackers网站的“讨论”功能。我在本地仓库中能够这样作:

step 1: 切换到develop分支

>>> git checkout develop

step 2: 分出一个功能性分支

>>> git checkout -b feature-discuss

step 3: 在功能性分支上进行开发工做,屡次commit,测试之后...

step 4: 把作好的功能合并到develop

>>> git checkout develop

    # 回到develop分支

    >>> git merge --no-ff feature-discuss
    # 把作好的功能合并到develop中

    >>> git branch -d feature-discuss
    # 删除功能性分支

    >>> git push origin develop
    # 把develop提交到本身的远程仓库中

这样,就完成一次功能的开发和提交。

release:预发布分支,当产品即将发布的时候,要进行最后的调整和测试,这时候就能够分出一个预发布分支,进行最后的bug fix。测试彻底之后,发布新版本,就能够把预发布分支删除。预发布分支通常命名为release-*

hotfix:修复bug分支,当产品已经发布了,忽然出现了重大的bug。这时候就要新建一个hotfix分支,继续紧急的bug修复工做,当bug修复完之后,把该分支合并到masterdevelop之后,就能够把该分支删除。修复bug分支命名通常为hotfix-*

releasehotfix分支离咱们还比较遥远。。就不详述,有兴趣的同窗能够参考本文最后的参考资料进行学习。

工做流(Workflow)

啰嗦讲了这么多,概念永远是抽象的。对于新手来讲,都喜欢一步一步的步骤傻瓜教程,接下来,咱们就一步一步来操做上面所说的工做流程,你们感觉一下:

Step 1:源仓库的构建

这一步一般由项目发起人来操做,咱们这里把管理员设为PingHackers,假设PingHackers已经为咱们创建起了一个源仓库PingHackers/git-demo,而且已经初始化了两个永久性分支masterdevelop,如图:

origin

Step 2:开发者fork源仓库

源仓库创建之后,每一个开发就能够去复制一份源仓库到本身的github帐号中,而后做为本身开发所用的仓库。假设我是一个项目中的开发者,我就到PingHackers/git-demo项目主页上去fork

fork

fork完之后,我就能够在我本身的仓库列表中看到一个和源仓库如出一辙的复制品。这时就应该感叹,你之后要和它相依为命了:

fork-origin

Step 3:把本身开发者仓库clone到本地

这一步应该不用教,git clone

Step 4:构建功能分支进行开发

进入仓库中,按照前面说所的构建功能分支的步骤,构建功能分支进行开发、合并,假设我如今要开发一个“讨论”功能:

>>> git checkout develop
    # 切换到`develop`分支

    >>> git checkout -b feature-discuss
    # 分出一个功能性分支

    >> touch discuss.js
    # 伪装discuss.js就是咱们要开发的功能

    >> git add .
    >> git commit -m 'finish discuss feature'
    # 提交更改

    >>> git checkout develop
    # 回到develop分支

    >>> git merge --no-ff feature-discuss
    # 把作好的功能合并到develop中

    >>> git branch -d feature-discuss
    # 删除功能性分支

    >>> git push origin develop
    # 把develop提交到本身的远程仓库中

这时候,你上本身github的项目主页中develop分支中看看,已经有discuss.js这个文件了:

push

Step 5:向管理员提交pull request

假设我完成了“讨论”功能(固然,你还可能对本身的develop进行了屡次合并,完成了多个功能),通过测试之后,以为没问题,就能够请求管理员把本身仓库的develop分支合并到源仓库的develop分支中,这就是传说中的pull request

pull-request

点击上图的绿色按钮,开发者就能够就能够静静地等待管理员对你的提交的评审了。

pull-finished

Step 6 管理员测试、合并

接下来就是管理员的操做了,做为管理员的PingHackers登录github,便看到了我对源仓库发起的pull request

pull-request-origin

这时候PingHackers须要作的事情就是:

  1. 对个人代码进行review。github提供很是强大的代码review功能:
    reivew
  2. 在他的本地测试新建一个测试分支,测试个人代码:

    >> git checkout develop
    # 进入他本地的develop分支
    
    >> git checkout -b livoras-develop
    # 从develop分支中分出一个叫livoras-develop的测试分支测试个人代码
    
    >> git pull https://github.com/livoras/git-demo.git develop
    # 把个人代码pull到测试分支中,进行测试
  3. 判断是否赞成合并到源仓库的develop,若是通过测试没问题,能够把个人代码合并到源仓库的develop中:

    >> git checkout develop
    >> git merge --no-ff livoras-develop
    >> git push origin develop

注意,PingHakers一直在操做的仓库是源仓库。因此咱们通过上面一系列操做之后,就能够在源仓库主页中看到:

merge

通过展转曲折的路程,咱们的discuss.js终于从个人开发仓库的功能分支到达了源仓库的develop分支中。以上,就是一个git & github协同工做流的基本步骤。

总结

git这一个工具博大精深,很难想象居然有使用如此恶心而又如此灵活和优雅的工具存在;此又为一神器,你们仍是多动手,多查资料,让git成为本身的一项基本技能,帮助本身处理各类项目团队协同工做的问题,成为一个高效的开发者、优秀的项目的管理者。送你们一张神图,好好领悟:

Overview

最后给出一些参考资料,供参考学习。

参考资料