DevOps系列文章之 Git知识大全

Git的工作原理

我们使用Git来记录每一次文件内容的变更,版本的更新,清晰地比较出不同版本的内容差异;可以使用Git在项目的历史版本自如地进行切换;还可以使用Git从当前项目的更改中撤销一些操作,可以新建分支,合并分支甚至关联远程服务器仓库等,这一切的背后都是怎么实现的?了解Git的思想以及基本原理这些操作也就略知一二了。

  • Git的分区

    • workspace: 工作区 直接编辑的地方,开发者可见具体的项目,可以直接操作项目文件
    • index(stage): 暂存区 数据暂存的地方
    • repository: 本地仓库 存放已提交的数据
    • remote: 远程仓库 在远程服务器上存放本地仓库的数据

DevOps系列文章之 Git知识大全_第1张图片

 

.git文件夹

  • .git下的文件夹

    • hooks 文件夹则存放项目的客户端或服务端钩子脚本
    • info 文件夹下的exclude文件包含项目全局忽略匹配模式,与.gitignore文件互补
      • exculd 文件
    • logs 保存所有更新的引用记录
      • refs
      • HEAD # 最后一次的提交信息
    • objects 文件夹存储着Git数据库的所有内容,存储所有Git的对象
      • info 记录对象存储的附加信息
      • pack 以压缩形式(.pack)存储许多对象的文件,附带索引文件(.idx)以允许它们被随机访问
    • refs 文件夹存储着所有分支指向各自提交对象的指针;本地分支,远端分支,标签等
      • heads 记录commit分支的树根
        • master 标识了本地项目中的master分支指向的当前commit的哈希值
      • remotes 记录从远程仓库copy来的commit分支的树根(只读)
        • origin
          • HEAD
          • master 标识了远端项目中的master分支指向的当前commit的哈希值。
      • tags 记录任何对象名称(不一定是提交对象或指向提交对象的标签对象)

.git下的文件

  • HEAD 文件指向当前分支, 包含了一个分支的引用,通过这个文件Git可以得到下一次commit的parent,可以理解为指针

  • index 文件存储着暂存区的内容信息

  • config 文件包含项目的配置信息

  • description 存储着仓库的描述信息,主要给gitweb等git托管系统使用

  • packed-refs 打包标头和标签以便高效的存储库访问

  • FETCH_HEAD 是一个版本链接,指向着目前已经从远程仓库取下来的分支的末端版本

  • ORIG_HEAD 记录的是在进行危险(drastic)操作(如合并merge,回退reset等)时,此操作之前HEAD所指向的位置,便于我们在发生毁灭性失误时进行回退

  • COMMIT_EDITMSG 保存最新的commit message,Git系统不会用到这个文件,只是给用户一个参考

DevOps系列文章之 Git知识大全_第2张图片

 

Git数据库

  • Git本质上是一个内容寻址文件系统(就是根据文件内容的hash码来定位文件。 这就意味着同样内容的文件,在这个文件系统中会指向同一个位置,不会重复存储。)Git 的核心部分是一个简单的键值对数据库,可以向该数据库插入任意类型的内容,它会返回一个键值,通过该键值可以在任意时刻再次检索(retrieve)该内容

  • Git 保存的不是文件的变化或者差异,而是一系列不同时刻的文件快照。在进行提交操作时,Git 会保存一个提交对象(commit object)。该提交对象会包含一个指向暂存内容快照的指针。 但不仅仅是这样,该提交对象还包含了作者的姓名和邮箱、提交时输入的信息以及指向它的父对象的指针。

  • git通过一种安全散列算法1(SHA-1)可以得到任意文件的SHA-1哈希值(40位的字符),也就是commit ID,然后通过文件哈希值存取数据,存取的数据都位于objects目录,SHA-1哈希值的前两个字符作为子目录名称,后 38 个字符则作为子目录内文件的名称

Git的数据存储原理

  • Git对象
    • 数据对象(blob object) 存储的是一个文件的具体内容

    • 树对象(tree object) 存储的文件的目录,一大坨指针,指向子级tree,或者blob

    • 提交对象(commit object) 存储作者信息,提交者信息,注释,指向一个 big tree 的指针

    • 标签对象(tag object)它包含一个标签创建者信息、一个日期、一段注释信息,以及一个指针。

  • Git的底层命令、高层命令

Git常用命令共有30多个,可运行git help查看;但Git总共有130多个命令,可以通过git help -a查看,这些命令可以分为高层命令和底层命令,底层命令被设计成unix风格,不常用

DevOps系列文章之 Git知识大全_第3张图片

 

      • 往Git数据库存入数据

      • 往Git数据库取出数据

      • 首次提交 testA.txt文件

      • 第二次提交,修改了test.txt文件内容

      • 第三次提交,增加一个新文件 testB.txt ,一个新目录 lib ,lib 里增加一个文件 testC.txt

      • 第四次提交,新建一个分支 branchB,并且在新分支中做了一次 commit

      • 第五次提交, 合并一分支

  • Git的引用(reference或refs)
    • 浏览完整的提交历史,但为了能遍历那段历史从而找到所有相关对象,需要记住最后提交的SHA-1值。我们需要一个文件来保存 SHA-1 值,并给文件起一个简单的名字,然后用这个名字指针来替代原始的 SHA-1 值。文件被称为“引用(references,或缩写为 refs)”,使用git branch (branchname) 这样的命令时,Git 实际上会运行 update-ref 命令,取得当前所在分支最新提交对应的 SHA-1 值,并将其加入你想要创建的任何新引用中。

    • 标签引用
    • 远程引用
      • 如果你添加了一个远程版本库并对其执行过推送操作,Git 会记录下最近一次推送操作时每一个分支所对应的值,并保存在 refs/remotes 目录下
    • HEAD引用
      • 分支和标签都是指向提交对象的指针,所有的本地分支都存储在 git/refs/heads 目录下,每一个分支对应一个文件
      • Git 分支的本质:一个指向某一系列提交之首的指针或引用

Git的对象模型

5. Gitflow工作流

  • Gitflow工作流约定使用的分支简介

    • master分支为项目的核心分支,也是最终对外发布的分支,唯一且稳定。仅提供可读,不可在该分支上直接修改代

    • develop分支是项目的开发主干分支,唯一。仅提供可读,不可在该分支上直接修改代码。新功能的开发需从该分支拉取新的分支展开。develop分支应该包含项目完整的全部历史记录。

    • featrue分支项是目的需求开发分支,可多个,从develop分支或其他featrue分支拉取。程序员的多人分工协作即通过featrue来实现,是代码具体实现的一线程序员接触最多的分支。需求开发完成后,要合并回develop分支。

    • release分支为预发布分支,通常被叫做测试分支,主要用于开发阶段的测试及bug修复。当feature分支开发完毕后会合并回develop分支,然后再从develop分支拉取release分支提测。测试并修复后的release分支要合并回develop分支以及master分支,并打上合适的tag标记(包含必要的releaseNote)。

    • hotfix分支为紧急线上修复分支,即当对外发布的master分支出现重大bug,影响线上使用时,从master分支拉取hotfix分支进行紧急修复。修复后的hotfix分支要合并回master分支和develop分支。

DevOps系列文章之 Git知识大全_第4张图片

 

  • GitFlow工作流程

DevOps系列文章之 Git知识大全_第5张图片

 

先,完成中央仓库的初始化,将新项目搭建起框架后的工程代码或要转gitflow的项目代码上传至git中央仓库。项目负责人克隆中央仓库到本地形成master分支,并拉取develop分支(步骤①)推送至服务器。一般的实际场景,开发团队中只有项目负责人有权限操作master分支,拉取develop分支,并将develop分支的代码合并到master分支中。

然后,开发团队中的其他人克隆中央仓库的develop分支到本地,形成全体成员统一的唯一的develop分支轨迹。之后,按照需求及成员各自的分工,各个成员可以从develop分支拉取出各自的featrue分支(步骤②)进行独立的开发;若涉及到多人合作开发同一分支,拉取的分支要及时推送至服务器,便于各成员共享。

当各成员完成各自的功能开发后,需将完成后的代码提交到featrue分支,然后合并到develop分支(步骤③)。代码合并后,featrue分支可以不再保留。

功能累积足够且稳定或到达约定的提测周期时,项目负责人应当从develop分支拉取出release分支(步骤④),打包提交相应的版本给测试人员进行部署测试,测试中提交的bug全部在该release分支完成修改。

测试结束并完成bug修复后,release分支应该合并回develop分支和master分支(步骤⑤),代码合并后,release分支可以不再保留。合并后的master分支,应由项目负责人及时推送到中央仓库(步骤⑥)。同时全体成员要及时同步自己develop分支。

有上线需求时,直接从master分支打包提交应用版本进行部署。当线上版本出现重大bug,项目负责人需从master分支拉取hotfix分支(步骤⑦),进行线上的紧急修复。

最后,修复后的hotfix分支要合并回develop分支和master分支(步骤⑧)。并推送到中央仓库(步骤⑨)。

你可能感兴趣的:(git)