Pro Git 阅读理解:Git 是如何实现的

前言

文章是对 Pro Git 第一版的阅读总结,因本人更关注 Git 的实现原理,所以文章只包含了个人认为对理解 Git 内部原理有帮助的第 1、3、4、7、9 章内容的总结,如果你也想深入的了解 Git,推荐阅读 Pro Git 的第一版和第二版:

Git 基础

Git 是一个分布式版本管理系统,与集中式版本管理系统不同,Git 几乎所有的操作都在本地进行,可以在本地进行提交更新等操作而无须联网;在 clone Git 仓库时,实际是将整个仓库镜像克隆下来,镜像包含了所有的历史提交记录,这意味着即使远程仓库丢失或损坏了,也可以轻易的通过本地仓库重建远程仓库。

Git 只关注数据整体的变化,而不是文件内容的具体差异:将变化的文件作快照后,记录在一个微型的文件系统中。每次提交更新时,Git 计算所有文件的指纹信息,存储文件快照,将文件对应的指纹作为引用指向文件快照。如果文件没有变化,Git 不会再次保存,只是链接到对应的文件快照。

Pro Git  示例

Git 在每次更新提交时,对每个文件进行校验计算,这意味着不会出现文件被修改但 Git 毫无所知的情况,最大程度的保证了文件的完整性。

Git 中文件只有三种状态:

  • 已提交(committed)表示文件已安全的保存到本地数据库中
  • 已修改(modified)表示修改了某个文件,还没有提交保存
  • 已暂存(staged)表示把已修改的文件放在下次提交时要保存的清单中

三种状态对应 Git 的三个工作区域:工作区,暂存区域,以及本地仓库

  • 工作区是从本地仓库中取出的某个版本的所有文件和目录,实际是从 Git 目录中的压缩对象数据库中提取的
  • 暂存区域是个简单的文件,一般都放在 .git/objects 目录中

Git 简单结构

Git 通过 HEAD 文件保存当前的分支,查看 .git/HEAD 中的内容:

20240118171359

这表明当前分支是 .git/refs/heads/master,查看对应的文件内容:

20240118171811

这是一个 40 位的指纹信息,引用到具体的文件;Git 以 40 位指纹的前两位作为目录名,剩余的 38 位作为文件名存储文件快照,这些文件都存放在 .git/objects 中:

20240118172610

Git 使用 zlib 的 Deflate 算法压缩内容,需要解压才能看到有意义的文件内容,使用 nodejs 解压上面的 1d/7f00bcdea10b04ceab0d243d181f09a971bcd0 文件:

20240118175025

得到的内容如下:

20240118175252

Git 将他表示为一个 commit 对象,为了直观的感受,以 js 对象表示:

({
   
  /** 对象类型 */
  type: "commit",
  /** 后续内容包含的字节数 */
  contentByteLenght: 178,
  /** 指向 root tree 对象 */
  tree: "87f0a1ed873d2b2836c5454462d938d874504aec",
  /** 指向上一次的提交对象,如果是第一次 commit 则不存在 */
  parent?: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  /** 作者 */
  author: {
   
    name: "yuanyxh",
    email: "xxxx@xxx.xxx",
    timestamp: 1705569456,
    reviseTime: "+0800",
  },
  /** 提交者 */
  committer: {
   
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值