来自所有版本控制系统的提交中的哈希冲突
Hash collision in commits from all version control systems
我读了Hash collision in git
由此看来 git 中的两个不同提交不太可能具有相同的哈希值。
但是除了 git 之外的所有提交又如何呢?我的应用程序使用 git,svn,hg - 我可以假设不会有相同哈希的不同提交吗?
现在我正在尝试考虑如何阻止我的应用程序从数据库中一个回购的不同分支创建相同的提交。
我弄清楚我可以在 db unique 中对哈希列做什么,如果我已经提交了这个哈希 - 就跳过它。
但是我不知道我是否有 big/small 机会跳过唯一提交而不是已经存在的提交的副本。
git 和 mercurial 都使用 sha1
来生成哈希,所以我会说两个不同的提交具有相同哈希的概率,一个来自 git,一个来自 mercurial与两次不同的 git 提交具有相同的哈希值相同。
Svn 不使用散列来识别提交,而是使用增量修订号,因此您在这里没有任何冲突问题
TL;DR:除非你混合 VCS,否则你是安全的。
你问题中的问题陈述一开始就不太正确:
... it appears what very unlikely what two different commits in git will have same hash.
这(间接地)导致了错误的进一步假设:
But what about all commits not only git? My application working with git,svn,hg - can i assume that there will be no different commits with same hash?
即使所有的 VCS 都是完美的,你也不能真的做出这个假设。即使所有的 VCS 都是完美的 和 使用相同的散列 算法 ,你仍然不能做出这个假设。但是对于您的特定问题,有一个更简单(尽管不完美)的答案。
For now i'm trying to deside how stop my application from creation same commits from different forks of one repo in db ...
这里要考虑的主要事情是 "forks of one repo" 的概念,以及您将如何识别特定提交。
如果我们查看 Git 或 Mercurial 中的提交标识,我们会发现它 是 哈希 ID。
Git 中的两个 object 具有相同的 object-ID 是 相同的 object,根据定义,因为Git 将仅存储任何 object 一次。这是因为 Git 的底层存储模型是一个简单的 key-value 存储,键是哈希 ID。任何一个键下都只存储一个值。
为了允许 Git 中的四种 object 类型——提交、带注释的标记、树和 blob——Git 将 object 的类型存储在header 放在所有 object 的前面。它假设将字符串 commit <size>[=10=]
添加到某些数据会导致与将字符串 blob <size>[=11=]
添加到相同数据不同的散列。这个假设在很大程度上是正确的,尽管鸽巢原理告诉我们必须有一些数据是错误的。 (就 SHA-1 的良好程度而言,找到产生碰撞的 data-pair 的机会是 2160 中的 1。Stevens 等人的工作表明 SHA- 1 不太好。)
无论如何,Git 的底层存储模型意味着一旦键具有关联值,key/value 对现在就被占用,并且不能再次存储与 same 键的对。因此,如果某个现有键 k 存在,并且具有类型 commit 并表示某个提交,则 [=43= 的新 object 不存在]any key k 类型可以添加到存储库数据库中(至少在不先删除现有 object with key k 的情况下).
这意味着如果您假设提交未被删除,并且如果您已经看到密钥 k 之前存在于此存储库的任何克隆中,则任何 other 密钥 k 的克隆具有 same object。哈希,换句话说,是 object,在一个非常真实的意义上。
在 Mercurial 中不一定如此。 Mercurial 的数据库 可以 存储具有重复键的新提交(与每个 object 关联的简单本地序列号可以消除它们的歧义)。但是,此类提交永远不会从一个存储库转移到另一个存储库(并且可能会导致其他问题),因此如果存储库将被分发,您当然可以假设问题已解决。
目前,Git 和 Mercurial 都使用 SHA-1,但它们以 不同的方式使用 。也就是说,计算散列的输入消息在 Git 与 Mercurial 中不同。 this 的意思是,如果你有 "forks" G(通过 Git 存储)和 M (通过 Mercurial 存储)代表相同的 存储库 ,键 kG在 G 中(在数字上)与 键无关 kM 在 M.
因此,如果允许两个不同的分叉使用两个不同的底层 VCS,则不能假设两个不同的密钥代表两个不同的 object,也不能假设两个相同的密钥代表相同的 object.但是,如果您将它们限制在 相同的 VCS,您可能会做出这样的假设。
(SVN 根本不通过哈希来识别提交。由于 SVN 存储库是集中式的,它们可以并且确实使用一个简单的唯一整数来表示每个提交。通过将 SVN 存储库转换为 Git 存储库,但是,您施加了 Git 限制:您现在拥有一个满足 both VCS 施加的任何限制的存储库。如果有人向 SVN 存储库添加无法表示的新提交在 Git 存储库中正确,它根本不会进入 Git 存储库。)
我读了Hash collision in git 由此看来 git 中的两个不同提交不太可能具有相同的哈希值。
但是除了 git 之外的所有提交又如何呢?我的应用程序使用 git,svn,hg - 我可以假设不会有相同哈希的不同提交吗?
现在我正在尝试考虑如何阻止我的应用程序从数据库中一个回购的不同分支创建相同的提交。 我弄清楚我可以在 db unique 中对哈希列做什么,如果我已经提交了这个哈希 - 就跳过它。 但是我不知道我是否有 big/small 机会跳过唯一提交而不是已经存在的提交的副本。
git 和 mercurial 都使用 sha1
来生成哈希,所以我会说两个不同的提交具有相同哈希的概率,一个来自 git,一个来自 mercurial与两次不同的 git 提交具有相同的哈希值相同。
Svn 不使用散列来识别提交,而是使用增量修订号,因此您在这里没有任何冲突问题
TL;DR:除非你混合 VCS,否则你是安全的。
你问题中的问题陈述一开始就不太正确:
... it appears what very unlikely what two different commits in git will have same hash.
这(间接地)导致了错误的进一步假设:
But what about all commits not only git? My application working with git,svn,hg - can i assume that there will be no different commits with same hash?
即使所有的 VCS 都是完美的,你也不能真的做出这个假设。即使所有的 VCS 都是完美的 和 使用相同的散列 算法 ,你仍然不能做出这个假设。但是对于您的特定问题,有一个更简单(尽管不完美)的答案。
For now i'm trying to deside how stop my application from creation same commits from different forks of one repo in db ...
这里要考虑的主要事情是 "forks of one repo" 的概念,以及您将如何识别特定提交。
如果我们查看 Git 或 Mercurial 中的提交标识,我们会发现它 是 哈希 ID。
Git 中的两个 object 具有相同的 object-ID 是 相同的 object,根据定义,因为Git 将仅存储任何 object 一次。这是因为 Git 的底层存储模型是一个简单的 key-value 存储,键是哈希 ID。任何一个键下都只存储一个值。
为了允许 Git 中的四种 object 类型——提交、带注释的标记、树和 blob——Git 将 object 的类型存储在header 放在所有 object 的前面。它假设将字符串 commit <size>[=10=]
添加到某些数据会导致与将字符串 blob <size>[=11=]
添加到相同数据不同的散列。这个假设在很大程度上是正确的,尽管鸽巢原理告诉我们必须有一些数据是错误的。 (就 SHA-1 的良好程度而言,找到产生碰撞的 data-pair 的机会是 2160 中的 1。Stevens 等人的工作表明 SHA- 1 不太好。)
无论如何,Git 的底层存储模型意味着一旦键具有关联值,key/value 对现在就被占用,并且不能再次存储与 same 键的对。因此,如果某个现有键 k 存在,并且具有类型 commit 并表示某个提交,则 [=43= 的新 object 不存在]any key k 类型可以添加到存储库数据库中(至少在不先删除现有 object with key k 的情况下).
这意味着如果您假设提交未被删除,并且如果您已经看到密钥 k 之前存在于此存储库的任何克隆中,则任何 other 密钥 k 的克隆具有 same object。哈希,换句话说,是 object,在一个非常真实的意义上。
在 Mercurial 中不一定如此。 Mercurial 的数据库 可以 存储具有重复键的新提交(与每个 object 关联的简单本地序列号可以消除它们的歧义)。但是,此类提交永远不会从一个存储库转移到另一个存储库(并且可能会导致其他问题),因此如果存储库将被分发,您当然可以假设问题已解决。
目前,Git 和 Mercurial 都使用 SHA-1,但它们以 不同的方式使用 。也就是说,计算散列的输入消息在 Git 与 Mercurial 中不同。 this 的意思是,如果你有 "forks" G(通过 Git 存储)和 M (通过 Mercurial 存储)代表相同的 存储库 ,键 kG在 G 中(在数字上)与 键无关 kM 在 M.
因此,如果允许两个不同的分叉使用两个不同的底层 VCS,则不能假设两个不同的密钥代表两个不同的 object,也不能假设两个相同的密钥代表相同的 object.但是,如果您将它们限制在 相同的 VCS,您可能会做出这样的假设。
(SVN 根本不通过哈希来识别提交。由于 SVN 存储库是集中式的,它们可以并且确实使用一个简单的唯一整数来表示每个提交。通过将 SVN 存储库转换为 Git 存储库,但是,您施加了 Git 限制:您现在拥有一个满足 both VCS 施加的任何限制的存储库。如果有人向 SVN 存储库添加无法表示的新提交在 Git 存储库中正确,它根本不会进入 Git 存储库。)