我现在已经多次提到这一点,Git提供了数据完整性。但这意味着什么?
据我所知,使用SHA-1校验和访问git中的所有对象,并根据文件内容计算此校验和。这意味着如果文件有更改,您将获得不同的校验和。
但是,它如何提供数据完整性?如果我查找一些基于校验和(密钥)的数据,如果找不到它(如果它已经以某种方式被破坏)将git返回错误。我假设在使用git-disk read errors等时数据仍然会被破坏。
不要真正看到与这里的SVN或者如何在Git中提供数据完整性。
答案 0 :(得分:5)
如果我根据校验和(密钥)查找某些数据,如果找不到它(如果它已经被破坏),git将返回错误。
基本上,是的。假设原始的正确数据校验和为1234.Git存储该校验和并通过该校验和查找数据。 (这就是它的内容可寻址"事物的工作原理:一般通常以例如master
之类的分支名称开头,它映射到像56789ab...
这样的提交ID。这个映射是保留在git" refs"中,比其他数据更容易受到攻击,但我们暂时假设此部分保持不变。)
Git然后按ID提取树内容,并将内容的校验和与ID进行比较。这必须匹配,否则树内容已损坏。假设内容有效,它们包含一系列给出文件模式,名称和ID的元组。对于每一行,模式区分其他树或普通文件(" blob")。名称是子树或文件的名称,ID是内容的校验和。
然后,Git按ID提取子树或blob内容,并比较校验和。这必须匹配,否则内容已损坏。假设内容有效,则像以前一样递归处理子树,并且文件是正确的(不妥协)。请注意,在此过程中,任何捕获的错误只会告诉您某些内容出错,但它无法解决问题;为此,您需要备份(例如存储库的另一个副本)。如果故障在整个过程中发生得相当远,那么很明显它是腐败的数据,因为校验和有效的时间足以找到提交和树,也许还有几个子树。故障。
如果引用已损坏,则很难重建。但是,git可以遍历数据库中的每个对象,看看是否有任何"未引用"。这些对象是应该指向的已损坏引用的候选对象。实际上,在实践中修复它通常是毫无意义的:你只需要在损坏的blob的情况下使用相同的备份。
答案 1 :(得分:4)
但是,它如何提供数据完整性?如果我查找一些基于校验和(密钥)的数据,如果找不到它(如果它已经以某种方式被破坏)将git返回错误。
是
根据数据,我并不仅仅意味着文件的内容,而是完整的历史记录(即,如果文件的给定版本的父版本发生更改,则与Git repo关联的所有SHA1都会发生变化。数据仍然存在,但其历史的其他部分已经改变。
我认为使用git-disk read errors等时数据仍然会被破坏。
这是腐败的一个例子 但即使数据保持不变,完整性也不会发生任何变化(即使在作者或提交者名称或日期等元数据中:更改其中一个,SHA1也会发生变化)
这是因为组成git repo的DAG graph数据:
(图片来自" Git Internals - Git Objects")
如果您修改其中任何一项,他们的父母也会改变。