git原理及如何选择分支模式

一、git 原理介绍

1.git的四个工作区域

  Git有四个工作区域:工作目录(Working Directory)、暂存区(Stage/Index)、资源库(Repository或Git Directory)、git仓库(Remote Directory)。

git原理及如何选择分支模式

 2.文件的四种状态

  Untracked:未跟踪, 此文件在文件夹中, 但并没有加入到git库, 不参与版本控制. 通过git add 状态变为Staged.

  Staged:暂存状态. 执行git commit则将修改同步到库中, 这时库中的文件和本地文件又变为一致, 文件为Unmodify状态. 执行git reset HEAD filename取消暂存,文件状态为Modified;

     Mosified:文件已修改, 仅仅是修改, 并没有进行其他的操作. 

  Committed: 文件已提交修改;

3.git的目录结构:

  进入隐藏的 .git 目录之后可以看到如上图所示结构

  核心文件:config,objects,HEAD,index,refs 这 5 个文件夹

  • config:这里存储项目的一些配置信息,比如是否以 bare 方式初始化,remote 信息等。git remote add 添加的远程分支信息就保存在这里
  • objects:这里保存 git 对象,git 中的一些操作以及文件都会以 git 对象形式保存在这里,git 对象分为 BLOB,tree,commit 三种类型,比如 git commit 就是 commit 类型变量,各个版本之间通过版本树进行组织,比如 HEAD 指向某个 commit 对象,而 commit 对象又会指向几个 BLOB 对象或者 tree 对象。objects 文件夹中有很多子文件夹,其中 git 对象保存在以其 sha-1 值的前两位为子文件夹后 38 位为文件名的文件中,此外 git 为了节省存储对象所占用的磁盘空间,会定期对 git 对象进行压缩和打包,其中 pack 文件夹用于存放打包压缩的对象,info 文件夹用于从打包的文件中查找 git 对象
  • HEAD:该文件指明了本地的分支结果,如本地分支是 master,那么 HEAD 就指向 master,分支在 refs 中就会表示成refs:refs/heads/master
  • index:该文件 stage 暂存区信息,也就是 add 之后保存到的区域,内容包括它指向的文件的时间戳,文件名,sha1 值等
  • refs:该文件夹保存了指向分支的提交对象也就是 commit 对象的指针,其中的 heads 文件夹存储了本地每一个分支最近一次提交的 sha-1 值,即 commit 对象的 sha-1 值,每个分支一个文件;remotes 文件夹则记录你最后一次和远程仓库的通信,也就是说这里会记录最后一次每个分支推送到远端的值;tags 文件夹存储分支别名

二、项目中如何选择分支模式

  在项目开发的过程中,选择一个合适的分支模式来管理代码至为重要,那么如何根据这身的业务特点和团队规模来选择合适的分支模式呢?这部分将对几种主流的Git分支模式进行介绍,下边将介绍TBD(主干开发模式)、Git-Flow模式、Github-Flow和Gitlab-Flow模式。

1.TBD(主干开发模式)

  TBD,即主干开发模式,所有的开发都在一个开发分支上进行协作开发,只保留一条长期稳定的开发分支,不允许新建任何长期存在的开发分支,任何代码的变更都更新到主干分支上,当需要发布时,建议根据版本号拉一个release分支进行发布,可以通过merge或者cherry pick将代码弄到发布分支上。

git原理及如何选择分支模式

TBD模式注意点:

  1.因为所有的改动及变更都在主干分支上,所以确保改动足够小,每次的改动都是可控的,能段时间完成验证;

  2.每次主干分支上的改动能得到快速验证,有完善的团队协作及自动化测试,随时做好上线的准备,避免引主干上的功能缺陷而影响发布。

  因为主干开发要求每次变更提交都要小,并且要快速验证完,保证主干是处在可发布状态。对于一些处在开发过程中的特性,如每次变更提交,并非意味着完整特性的完成,为了隔离“特性半成品”对主干的影响,一般会采用特性开关(Feature Toggle)的方式进行隔离。即频繁的代码变更提交,可以先做集成及验证,但是在发布的角度,通过(Feature Toggle)先隐藏相关特性,只有当特性都完成之后,才打开开关,特性完全透出。

TBD模式优点:

  1.分支少,合并冲突小,实践简单;

  2.适合持续交付及部署,简单密集需求交付

TBD模式缺点:

  1.对团队协作及成熟度合集成测试有很高的要求;

  2.不适合开发一些持续时间长的需求及功能复杂的业务;

2.Git-Flow模式

  随着敏捷开发的广泛使用,越来越多的团队协作完成某一特性或者分别完成不用的用户故事,根据不同的特性或者用户故事来创建开发分支就应运而生。最有代表性的就是Git-Flow模式。

  Git-Flow 模式很好解决了不同特性之间并行开发需要的工作方式。每一个特性都能同时开工,结合敏捷开发的例子,每个迭代开始时从主干分支拉出一个特性分支,命名结构参考feature/xxx-232,所有关于此特性的开发都在此分支上进行,当开发完成后把特性分支合并回主干分支上,测试通过后进行发布。

git原理及如何选择分支模式

Git-Flow模式一般有以下分支结构:

  • feature分支:开发者进行特性功能开发的分支;
  • develop分支:开发主干分支,包含所有的特性功能;
  • release分支:版本发布分支;
  • master分支:稳定分支,保存最新的已发布代码;
  • hotfix分支:线上问题缺陷修复分支;

  下面是一些工作流程:

  在开发者接到一个开发需求时,从develop分支拉一个feature分支进行开发,最好已ID进行命名,避免重复,为了减少后边合入develop的冲突,最好在开始coding前把develop分支合到feature分支上再进行开发;

  当在feature分支完成开发并验证通过后,将feature分支合入develop分支;

  develop分支用于集成功能验证,当集成测试成功后将基于develop分支拉一个release版本分支进行发布,如果在release上测试发现bug则在release上修复,之后将代码合入develop,当上线完成后将release合入master分支进行最新上线代码保存;

  如果线上发现bug,则基于master拉一条hotfix分支进行修复,修复完成后将hotfix分支合入master进行发布,最后将hotfix代码也同步到develop上。

  注意:对一些已完成的feature分支及hotfix分支进行及时删除。

Git-Flow模式的优点

  1.特性并行开发,效率高,代码独立;

  2.支持复杂业务、大团队协同开发;

  3.支持多版本发布;

Git-Flow模式的缺点

  1.分支多,合并冲突较为频繁

  2.需要进行维护分支,对分支代码进行更新

3.Github-Flow 模式

  Github-Flow就是简化版的Git-Flow,更轻量,减少分支。对于 GitHub-Flow 来说,发布应该是持续地,当一个版本准备好,它就可以被部署,feature跟hotfix本质上都是一样的,都属于特性分支,并移除了release分支。

git原理及如何选择分支模式

 分支情况如下:

  在master分支上的代码都是最新的,可部署的;

  在特性分支合到master分支时需要发起Pull Request代码评审,评审后方可合入master;

  在master上进行持续版本发布。

优点:

  1.支持并行开发;

  2.分支结构简单,有明确的规则定义,持续集成持续部署

缺点:

  1..对测试要求高,一些功能复杂的需求需要持续长的时间验证或者中断则影响整个计划;

  2.不能很好的处理一些很紧急的上线需求;

4.Gitlab-Flow模式

  GitLab-Flow 相比于 GitHub-Flow 来说,在开发侧的区别不大,只是将 pull request 改成了 merge request,而 merge request 的用法与 pull request 类似,都可以做为代码评审、获取反馈意见的一种沟通方式。
最大的区别体现在发布侧,即引入了对应生产环境的 production 分支和对应预发环境的 pre-production 分支(如果有预发环境的话)。这样,master 分支反映的是部署在集成环境上的代码,pre-production 分支反映的是部署在预发环境的代码,production 分支反映的最新部署在生产环境的代码。
  当一个特性开发完成,提交 merge request,将特性开发的代码合并到 master,并部署到集成环境进行验证;当验证通过之后,提交 merge reqeust,合并 master 到 pre-production 分支,并部署到预发环境,进行预发环境上验证;当预发环境验证成功之后,再提交 merge request,将 pre-production 分支上的代码合并到 production 分支上。

  git原理及如何选择分支模式

三、分支总结

  根据每个项目的实际情况的不同选择不同的分支模式:

  1.git-flow模式对于开发周期长的项目是比较好的选择,可以很好解决新功能开发,版本发布,线上问题修复等问题;

  2.如项目发布周期短,需持续发布维护,功能较为简单,TBD和GitHub-flow是个不错的选择;

  3.如果对一些复杂功能的上线前增加一些验证,可选gitlab-flow模式。

  还有一些其他的分支策略,比如定义一个主干分支,然后每个成员已自己名字命名的开发分支等等,结合我们的业务需求选择分支策略最为重要。

本文参考:

公众号:阿里技术,作者:张燎原,如何选择Git分支模式?