编辑
2025-03-24
技术杂谈
00
请注意,本文编写于 136 天前,最后修改于 134 天前,其中某些信息可能已经过时。

目录

git 中的四种对象
git中的树对象
区域
ref区域
基础命令
hash-object
cat-file
update_index
write-tree
commit-tree
update-ref
symbolic-ref
git对象的存储
HEAD文件

我将会使用rust写一个mini-git, 本文旨在梳理git的基本原理.

git 中的四种对象

  • Blob对象:存储文件内容
  • Tree对象:存储目录结构和文件名,指向Blob对象

git中的树对象

如图, tree对象的子孙可以是blob, 也可以是tree(用于多级目录生成)

  • Commit对象:存储提交信息,指向Tree对象
  • Tag对象:为特定Commit提供标记

区域

  • 工作区: 写代码的区
  • 缓存区: git add的区
  • 本地仓库: 储存所有数据

ref区域

  • .git/refs/head 存储了所有的本地分支的引用(例如master)等等 文件名即分支名,每个文件存储了SHA1值
  • .git/refs/tags 存储了所有的本地版本号的引用(例如v1.0.0)等等

基础命令

hash-object

hash-object命令可以把一个文件或者标准输入哈希,存在.git/objects中

哈希值前两位用作目录索引, 如d670460b4b4aece5915caf5c68d12f560a9fe3e4存储路径为

bash
.git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4
  • -w 用于真正生成文件
  • --stdin 用于从标准输入中获取

cat-file

cat-file 用于显示文件

  • -p 用于显示文件内容
  • -t 用于显示文件类别

update_index

用于把文件加入暂存区,同时需要指明文件权限,SHA1,文件名

  • --add 之前不在暂存区
  • --cacheinfo 添加到git目录中(而不是当前目录)

write-tree

将暂存区内容写入tree对象中,无需其它参数

commit-tree

将一个tree对象进行提交

  • -m commit信息
  • -p 父提交(用于构建有向无环图)

update-ref

编辑引用文件

bash
git update-ref refs/heads/master 1a410efbd13591db07496601ebc7a059dd55cfe9

symbolic-ref

编辑head文件

git对象的存储

  • 把信息头放在内容之前
blob {context.len}\0
  • SHA1这个拼接的字符串
  • 使用zlib压缩并存在对应的文件

HEAD文件

HEAD文件是一个引用,指向refs中的文件

bash
$ cat .git/HEAD ref: refs/heads/master

可以使用symbolic-ref