在仓库的 .git/objects
目录下, 保存着 git 的 object.
后面以这个 Demo Repo 为例.
.git/objects
├── 11
│ └── ef4924f8f1e21e6d7412040973f5e868559ac7
├── 16
│ └── 796efecb4599c92244ac8bafb217e20009008e
├── 20
│ └── 61bac5e1a292b380f98072ef5ffbc2fc3eefa9
├── 53
│ └── 33c1763419c89486091d80b6ba430d30b321a0
├── 67
│ └── 89c99cbe4a25ecc9e69eb1e66df819ddfab2e5
├── 69
│ └── 15089af93052dc6f67fd7245037230a6b1894b
├── d0
│ └── 38440f5c27d52fed6b6c5eb7d180f1645ab724
├── f2
│ └── 0b9ed4f8ba4e99df6a2491bbed85e8daf526d5
├── info
└── pack
cat-file
查看 object 的类型:
git cat-file -t 16796efecb4599c92244ac8bafb217e20009008e
blob
查看 object 的内容:
git cat-file -p 16796efecb4599c92244ac8bafb217e20009008e
# Help
save object to disk
Git object 有几个类型:
- blob
- tree
- commit
Git object 内部以文本为基础, 经过特殊的编排, 再经过压缩, 最终得到的是二进制文件.
为了查看其内部的原始文本, 第一步就是需要接开压缩.
我们定义一个解压脚本, 参数是 Git object 的文件路径:
alias inflate="ruby -r zlib -e \"ARGV.each {|path| puts Zlib::Inflate.inflate File.read(path) }\""
后面还会用到 hexdump
, 它会帮我们以 16 进制的形式来展示内容本来的面目, 特别注意那些不能打印的字符.
常见字符对照:
16 进制 | 字符 |
---|---|
00 |
NULL 空 |
20 |
空格 |
21 |
叹号 ! |
22 |
引号 " |
23 |
井号 # |
2E |
句号 . |
30 |
数字 0 |
39 |
数字 9 |
41 |
字母 A |
5A |
字母 Z |
61 |
字母 a |
7A |
字母 z |
0A |
换行 line feed |
0D |
回车 carriage return |
hexdump -C
既会打印 16 进制的内容, 也会打印对应的可视字符(不可打印的用 .
表示).
blob
git cat-file -p 16796efecb4599c92244ac8bafb217e20009008e
# Help
inflate .git/objects/16/796efecb4599c92244ac8bafb217e20009008e | hexdump -C
00000000 62 6c 6f 62 20 38 00 23 20 48 65 6c 70 0a 0a |blob 8.# Help..|
0000000f
blob 编码结构:
blob | 空格 | 内容长度 | NULL | 文件内容 |
tree
git cat-file -p 11ef4924f8f1e21e6d7412040973f5e868559ac7
100644 blob 16796efecb4599c92244ac8bafb217e20009008e help.md
100644 blob f20b9ed4f8ba4e99df6a2491bbed85e8daf526d5 info.md
inflate .git/objects/11/ef4924f8f1e21e6d7412040973f5e868559ac7 | hexdump -C
00000000 74 72 65 65 20 37 30 00 31 30 30 36 34 34 20 68 |tree 70.100644 h|
00000010 65 6c 70 2e 6d 64 00 16 79 6e fe cb 45 99 c9 22 |elp.md..yn..E.."|
00000020 44 ac 8b af b2 17 e2 00 09 00 8e 31 30 30 36 34 |D..........10064|
00000030 34 20 69 6e 66 6f 2e 6d 64 00 f2 0b 9e d4 f8 ba |4 info.md.......|
00000040 4e 99 df 6a 24 91 bb ed 85 e8 da f5 26 d5 0a |N..j$.......&..|
0000004f
tree 编码结构:
tree | 空格 | 内容长度 | NULL | <文件名a编码>文件名a编码> | <文件名b编码>文件名b编码> | 换行 LF |
文件名编码结构:
文件权限, 10064 | 空格 | 文件名 | 空格 | blob SHA, 40位 hex |
commit
git cat-file -p 6915089af93052dc6f67fd7245037230a6b1894b
tree 6789c99cbe4a25ecc9e69eb1e66df819ddfab2e5
author Baodong <wwwicbd@gmail.com> 1645015448 +0800
committer Baodong <wwwicbd@gmail.com> 1645015448 +0800
Init
inflate .git/objects/69/15089af93052dc6f67fd7245037230a6b1894b | hexdump -C
00000000 63 6f 6d 6d 69 74 20 31 35 39 00 74 72 65 65 20 |commit 159.tree |
00000010 36 37 38 39 63 39 39 63 62 65 34 61 32 35 65 63 |6789c99cbe4a25ec|
00000020 63 39 65 36 39 65 62 31 65 36 36 64 66 38 31 39 |c9e69eb1e66df819|
00000030 64 64 66 61 62 32 65 35 0a 61 75 74 68 6f 72 20 |ddfab2e5.author |
00000040 42 61 6f 64 6f 6e 67 20 3c 77 77 77 69 63 62 64 |Baodong <wwwicbd|
00000050 40 67 6d 61 69 6c 2e 63 6f 6d 3e 20 31 36 34 35 |@gmail.com> 1645|
00000060 30 31 35 34 34 38 20 2b 30 38 30 30 0a 63 6f 6d |015448 +0800.com|
00000070 6d 69 74 74 65 72 20 42 61 6f 64 6f 6e 67 20 3c |mitter Baodong <|
00000080 77 77 77 69 63 62 64 40 67 6d 61 69 6c 2e 63 6f |wwwicbd@gmail.co|
00000090 6d 3e 20 31 36 34 35 30 31 35 34 34 38 20 2b 30 |m> 1645015448 +0|
000000a0 38 30 30 0a 0a 49 6e 69 74 0a |800..Init.|
000000aa
commit 编码结构:
commit | 空格 | 内容长度 | NULL |
tree | 空格 | object SHA | 换行 LF |
author | 空格 | 作者名字 | 空格 | < | 作者 email | > | 空格 | 时间戳 | 空格 | 时区, +0800 | 换行 LF |
committer | 空格 | 提交者名字 | 空格 | < | 作者 email | > | 空格 | 时间戳 | 空格 | 时区, +0800 | 换行 LF |
换行 LF | commit message | 换行 LF |