Git 将文件存储为 blob,然后使用 SHA-1 校验和作为键来查找其他 blob 中的每个特定 blob,类似于标识文件的文件名。
那么这个黑魔法是如何工作的呢?也就是说,如何从文本文件开始,以 blob 结束?Blob 是通过取消引用文件的内存内存地址或其他东西创建的吗?
Git 中几乎没有真正的魔力。 非常神奇的一点是(是?(各种安全哈希算法(SHA(校验和设计,Git对这些校验和的使用,以及它们如何形成Merkle树,但这比其他任何东西都更像"数学魔术"。
我想你真的在问"Git 是如何想出哈希 ID 的",答案很简单:
- 查找文件的大小(以字节为单位(。 以十进制打印,例如
123
. -
将打印大小以十进制表示,放在单词
blob
和空格之后。 附加一个ASCII NUL字符,例如在Python中b' '
。 对前缀和数据进行哈希处理,结果是 Blob 的哈希 ID:$ python3 ... >>> data = b"some file datan" >>> prefix = "blob {} ".format(len(data)).encode("utf-8") >>> import hashlib >>> h = hashlib.sha1() >>> h.update(prefix) >>> h.update(data) >>> h.hexdigest() 'a831035a26dd2f75c2dd622c70ee22a10ee74a65'
我们可以使用 Git 的对象哈希器进行检查:
$ echo 'some file data' | git hash-object -t blob --stdin
a831035a26dd2f75c2dd622c70ee22a10ee74a65
哈希匹配,因此这是仅由 15 字节行"某些文件数据"组成的任何文件的 blob 哈希,并以换行符结尾。 请注意,决定哈希 ID 的是内容:此处的文件名无关紧要。 (这意味着文件名必须存储在其他位置 - 在 Git 中,存储在一个或多个树对象中。
(请注意,SHA-1 不再被视为加密安全。 Git 正在慢慢迁移到其他哈希算法,但这里并不着急。 请参阅新发现的 SHA-1 冲突如何影响 Git?