代码托管从业者 Git 指南 (2)

首先需要了解 Git 存储库的目录结构,Git 存储库分为常规存储库和 Bare (裸)存储库,普通用户从远程克隆下来的存储库,或者本地初始化的存储库大多是常规存储库,这类存储库和特定的工作区相关联;另一类是没有工作区的存储库,就是裸存储库,在代码托管平台的服务器上,存储库几乎都是以裸存储库的方式存储的。对于常规存储库而言,其存储库真正的路径是工作区根目录下的 .git 文件夹,或者 .git 文件指向的目录,后者通常用于 Git 子模块。

知道了 Git 存储库的位置,就可以查看存储库的目录结构,下面是一个查看存储库的截图。

代码托管从业者 Git 指南

不同的目录具备不同的作用,大致如下:

路径 属性 作用 备注
HEAD   R   存储当前检出的引用或者提交 ID   在远程服务器上用于展示默认分支  
config   R   存储库配置   存储库配置优先级高于用户配置,用户配置优先级高于系统配置  
branches   D   deprecated    
description   R   depracated    
hooks   D   Git 钩子目录,包括服务端钩子和客户端钩子   当设置了 core.hooksPath 时,则会从设置的钩子目录查找钩子  
info   D   存储库信息   dump 协议依赖,但目前 dump 协议已无人问津  
objects   D   存储库对象存储目录    
refs   D   存储库引用存储目录    
packed-refs   R   存储库打包引用存储文件   该文件可能不存在,运行 git pack-refs 或者 git gc 后出现  

在这些目录或者文件中,最重要的是 objects 和 refs ,只需要两个目录的数据就可以重建存储库了。在 objects 目录下,Git 对象可能以松散对象也可能以打包对象的形式存储:

路径 描述
objects/[0-9a-f][0-9a-f]   松散对象存储目录,最多有 256 个这样的子目录  
objects/pack   打包对象目录,除了打包对象,还有打包对象索引,多包索引等  
objects/info   存储存储库扩展信息  
objects/info/packs   哑协议依赖  
objects/info/alternates   存储库对象借用技术  
objects/info/http-alternates   存储库对象借用,用于 HTTP fetch  

Git 在实现其复杂功能的时候还会创建一些其他目录,更详细的细节可以查阅:Git Repository Layout。

Git 对象的存储

Git 的对象可以按照松散对象的格式存储,也可以按照打包对象的格式存储,用户将文件纳入版本控制时,Git 会将文件的类型标记为 blob,将文件长度和 \x00 以及文件内容合并在一起计算 SHA1 哈希值后,使用 Deflate 压缩,存储到存储库的 objects 目录下,路径匹配正则为 objects\/[0-9a-f]{2}\/[0-9a-f]{38}$,当然如果使用 SHA256 则应该匹配 objects\/[0-9a-f]{2}\/[0-9a-f]{62}$,松散对象的空间布局如下:

代码托管从业者 Git 指南

Git 使用的 Deflate 是 Phil Katz 为 PKZIP 创建的压缩算法,也是使用最广泛的压缩算法之一,其变体 GZIP 也被广泛用于 POSIX 文件压缩和 HTTP 压缩。Git 命令行,libgit2 目前依赖 zlib 提供 deflate 算法,jgit 则使用 Java 提供的 deflate 实现,Golang 则在 compress/zlib 包中提供 deflate 支持,但算法实现在 compress/flate,严格来说 Git 使用的是 deflate 的 zlib 包装,比如我们使用 zlib 创建 zip 压缩包时会使用 -15 作为 WindowBits,而在创建 GZIP 时会使用 31 作为 WindowBits,在 Git 中,则会使用 15 作为 WindowBits。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpdjwp.html