为什么git在'git add'命令之间创建新的blob?

问题描述 投票:1回答:2

所以我最近发现了工具git cat-file,我一直在玩它。我知道git使用blob来存储实际内容。但是为什么每次我改变文件时都会创建一个新的blob,即与编辑现有的blob,或者创建一个新的blob并删除旧的blob相反?

EG

git add

所以包含我的中间阶段变化的blob的目的,即包含“hello”的blob abc123并不明显。

在提交方面,touch hello.txt // change hello.txt to contains 'hello' git add hello.txt // creates a blob abc123 containing: 'hello' // change hello.txt to 'hello world' git add hello.txt // creates a blob cba321 containing: 'hello world' git commit // creates a commit with tree pointing at blob cba321 从“”直接转到“hello world”,我甚至无法在没有挖掘git blob的情况下取回我的中间变化abc123。

git tree blob git-index
2个回答
1
投票

但是为什么每当我git添加一个文件的更改时,它似乎创建一个新的blob,即与编辑现有的blob,或者创建一个新的blob并删除旧的blob相反?

没有blob可以改变。这与关于提交的规则相同:不能更改任何提交。

原因是每个Git对象-bbb和提交的哈希ID是四种类型的内部Git对象中的两种 - 只是作为该对象存储的内容的加密校验和。在文件(“blob”)的情况下,实际内容是五个ASCII字符hello.txtblo,space,然后blob的大小十进制并且还存储在ASCII中,然后是ASCII NUL字节,以及然后存储数据。例如,b存储为Python可能代表的hello

(您可以使用SHA1哈希或使用b"blob 5\0hello"计算此哈希:

git hash-object

要么:

$ echo -n hello | git hash-object --stdin
b6fc4c620b67d95f953a5c1c1230aaab5db5a1b0

所以任何带有哈希ID $ python3 [snip] >>> import hashlib >>> hashlib.sha1(b"blob 5\0hello").hexdigest() 'b6fc4c620b67d95f953a5c1c1230aaab5db5a1b0' 的blob都必须是文件b6fc4c620b67d95f953a5c1c1230aaab5db5a1b0,或者 - 如果不是 - 你不能在这个Git存储库中存储包含hello(没有换行符)的文件。找到一个文件(一个邪恶的双胞胎,阻止存储其他文件)的doppelgänger是非常重要的:请参阅hello了解详情。

因此,当您How does the newly found SHA-1 collision affect Git?文件时,Git会创建一个新的blob,或者重新使用现有的blob,具体取决于该文件的数据是否已作为存储库中的blob存在。如果你然后git add,Git永久保存内容,与新的提交对象相关联。如果你从未提交过那个blob,也没有其他提交或其他实体引用它,Git最终会通过垃圾收集过程使blob过期(参见git commit)。

(请注意,这些Git对象也是zlib放气,并且是所有四种Git对象类型的倒数第二个存储形式。但是,经过一段时间后,现有对象可能被打包到一个包文件中,在那里它们对其他对象进行增量压缩包装文件是最终的存储形式。包装对象可以在必要时解压缩,但在正常操作中,Git只是在扩展增量压缩的同时从包文件中动态提取解压缩的对象数据。)

(为了完整起见,另外两个Git对象类型是树和带注释的标记。树对象存储文件名,从名称到blob哈希ID的映射,以及文件的可执行位。提交对象通过哈希ID引用到表示快照的树。带注释的标记对象是一种特殊情况数据结构,它包含另一个Git对象的哈希ID以及数据有效负载;在此数据有效负载中,您可以存储GPG签名或其他一些数字签名,以及您喜欢的任何其他内容。然后,您可以将轻量级标记指向带注释的标记对象,以获取带注释的标记。)


1
投票

git gc确实创建了blob,因为索引(或临时区域,它有许多名称......)的目的是准备快照,这将构成下一次提交。

此外,您谈论编辑或删除blob,但这将违背该工具的原则,因为快照必须始终可重复,并且它引用的所有blob都不会被触及。在某种程度上,你永远不会修改任何东西,你只需添加更多的东西和关系。

回答你的最后一点,不,你不能“甚至”回到你认为不值得储蓄的状态。

© www.soinside.com 2019 - 2024. All rights reserved.