一、git 原理介绍

1.git的四个工作区域

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

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将代码弄到发布分支上。

TBD模式注意点:

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

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

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

TBD模式优点:

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

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

TBD模式缺点:

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

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

2.Git-Flow模式

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

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

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分支。

分支情况如下:

  在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 分支上。

  

三、分支总结

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

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

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

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

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

本文参考:

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

git原理及如何选择分支模式的更多相关文章

  1. jenkins实现手动选择分支构建项目-Git Paramater

    先下载插件: Git Paramater 参照: jenkins-参数化构建(三)插件:Git Parameter https://www.cnblogs.com/zhaojingyu/p/98624 ...

  2. git原理学习记录:从基本指令到背后原理,实现一个简单的git

    一开始我还担心 git 的原理会不会很难懂,但在阅读了官方文档后我发现其实并不难懂,似乎可以动手实现一个简单的 git,于是就有了下面这篇学习记录. 本文的叙述思路参照了官方文档Book的原理介绍部分 ...

  3. Git原理与命令大全

    Git (wiki: en  chs )是一个免费开源的分布式版本控制系统,由linux内核作者linus Torvalds开发,大型开源项目linux kernel.Android.chromium ...

  4. Git原理入门简析

    为了获得更好的阅读体验,建议访问原地址:传送门 前言: 之前听过公司大佬分享过 Git 原理之后就想来自己总结一下,最近一忙起来就拖得久了,本来想塞更多的干货,但是不喜欢拖太久,所以先出一版足够入门的 ...

  5. Git原理入门解析

    前言: 之前听过公司大佬分享过 Git 原理之后就想来自己总结一下,最近一忙起来就拖得久了,本来想塞更多的干货,但是不喜欢拖太久,所以先出一版足够入门的: 一.Git 简介 Git 是当前流行的分布式 ...

  6. git 学习笔记 —— 获取远端分支并修改后提交至远端仓库

    笔者最近进行开发过程中,所有参与者的代码需要通过 git 上传到远端仓库中,不同的模块对应不同的 git 分支,不同模块的数据需要从远端仓库中获取.这里记录下笔者从远端仓库中获取分支数据,进行修改,最 ...

  7. Git学习(四)——分支管理

    一.创建与合并分支 1.创建分支 一开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点.每次提交 ,mast ...

  8. 《Pro Git》笔记3:分支基本操作

    <Pro Git>笔记3:Git分支基本操作 分支使多线开发和合并非常容易.Git的分支就是一个指向提交对象的可变指针,极其轻量.Git的默认分支为master. 1.Git数据存储结构和 ...

  9. git学习笔记06-创建分支合并分支-比svn快多了,因为只有指针在改变

    一开始git只有一条时间线,这个分支叫主分支,即master分支. HEAD严格来说不是指向提交,而是指向master,master才是指向提交的,所以,HEAD指向的就是当前分支. 每次提交,mas ...

随机推荐

  1. CSS通过text-transform实现大写、小写和首字母大写转换

    再日常项目中可能会用到一些特殊的样式,比如大写字母转小写.小写字母转大写.首字母大写等. 可以通过 CSS 的 text-transform 属性来实现: text-transform 转换不同的文本 ...

  2. [ArcEngine二次开发]为Feature的属性赋值

    在创建FeatureClass之后,需要为FeatureClass添加Features,在为Feature的字段赋值时,代码大致如下: 在这里赋值的时候,出现了一个错误: The operation ...

  3. 如何理解Javascript中的函数(Function)

    Function类型 首先得知道,每个函数都是Function类型的实例,所以函数本身是对象. 示例1: function sum (num1, num2){ return sum1 + sum2; ...

  4. 一、Python系列——函数的应用之名片管理系统

    card_list = [] def main_desk(): print('*'*50) print('欢迎使用[名片管理系统]V1.0') print('1.新建名片') print('2.显示全 ...

  5. 【软件测试】Python自动化软件测试算是程序员吗?

    今天早上一觉醒来,突然萌生一个念头,[软件测试]软件测试算是程序员吗?左思右想,总感觉哪里不对.做了这么久的软件测试,还真没深究过这个问题.     基于,内事问百度的准则: 结果……     我刚发 ...

  6. Ubuntu18.04安装Docker并部署(编译、发布、构建镜像)Asp.NetCore项目全过程笔记

      环境准备:阿里云Ubuntu18.04 全新安装   一.安装Docker 1.删除旧版本并更新包索引: sudo apt-get remove docker docker-engine dock ...

  7. msf stagers开发不完全指北(四): msf 中使用域前置技术隐藏流量

    msf 中使用域前置技术隐藏流量 前几篇都是说了下如何采用不同的语言开发 reverse_tcp 第二阶段,接下来将慢慢分析 reverse_http,这篇文章并不会围绕 stagers 进行讲解,这 ...

  8. python 复制以及更改列表操作

    题目:设置一个老用户列表和一个新用户列表,检查老用户列表中是否与新注册的用户名字有重复(不区分大小写),老用户列表不能被破坏 usernames = ['admin','Tom','john','ja ...

  9. 微信小程序反编译~2020年

    目录 摘要 介绍 安装反编译脚本 使用 获取wxapkg文件 反编译 结论 参考资料 摘要 安装wxappUnpacker小程序反编译工具并使用(2020.03) 关键词: 微信小程序反编译 wxss ...

  10. 用c#自己实现一个简单的JSON解析器

    一.JSON格式介绍 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.相对于另一种数据交换格式 XML,JSON 有着很多优点.例如易读性更好,占用空间更 ...