【问题标题】:How does Git(Hub) handle possible collisions from short SHAs?Github) 如何处理来自短 SHA 的可能冲突?
【发布时间】:2011-10-31 00:04:32
【问题描述】:

Git 和 GitHub 都显示短版本的 SHA——仅显示前 7 个字符,而不是全部 40 个字符——而且 Git 和 GitHub 都支持将这些短 SHA 作为参数。

例如git show 962a9e8

例如https://github.com/joyent/node/commit/962a9e8

鉴于可能性空间现在低了几个数量级,“只是”268 million,Git 和 GitHub 如何在此处防止冲突?他们又是如何处理的?

【问题讨论】:

标签: git cryptography github sha


【解决方案1】:

这些简短的表格只是为了简化视觉识别并让您的生活easier。 Git 并没有真正截断任何内容,内部所有内容都将使用完整值进行处理。不过,您可以在方便时使用部分 SHA-1:

只要你的部分 SHA-1 至少有四个字符长且明确——也就是说,当前只有一个对象存储库以该部分 SHA-1 开头。

【讨论】:

  • 谢谢!该链接进一步详细说明:“Git 可以为您的 SHA-1 值找出一个简短、唯一的缩写。如果您将 --abbrev-commit 传递给 git log 命令,输出将使用较短的值但保持它们唯一;默认使用七个字符,但如果有必要使它们更长,以保持 SHA-1 明确。"
  • 另一个有用的引用:“一般来说,8 到 10 个字符足以在一个项目中保持唯一性。最大的 Git 项目之一,Linux 内核,开始需要 12 个字符。可能有 40 个保持独特性。”
  • 您的链接已损坏... :(
【解决方案2】:

我有一个存储库,其提交的 id 为 000182eacf99cde27d5916aa415921924b82972c

git show 00018

显示修订,但是

git show 0001

打印

error: short SHA1 0001 is ambiguous.
error: short SHA1 0001 is ambiguous.
fatal: ambiguous argument '0001': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions

(如果您好奇,它是 git 本身的 git 存储库的克隆;该提交是 Linus Torvalds 在 2005 年所做的。)

【讨论】:

  • 如果您需要知道哪些对象与您的模棱两可的 id 匹配(在这种情况下为0001),您可以使用git rev-list --all --objects | grep ^0001。在获得可能的完整 SHA1 列表后,您可以为每个 SHA1 执行 git show
  • This answer 展示了如何仅使用 git 命令来消除歧义。
【解决方案3】:

这里有两个注意事项:

  • 如果您在显示提交的 GitHub 页面上的任意位置键入 y,您将看到该提交的完整 40 字节。
    这说明了emboss 的观点:GitHub 不会截断任何内容。

  • 自 2010 年以来,7 个十六进制数字(28 位)还是不够的。
    请参阅 Linus Torwalds 本人的 commit dce9648(2010 年 10 月,git 1.7.4.4):

默认值 7 来自 git 开发的早期阶段,当时七个十六进制数字很多(它涵盖了大约 250+ 百万个哈希值)。那时我认为 65k 修订很多(这是我们即将在 BK 中达到的),并且每个修订往往在 5-10 左右 新对象左右,所以一百万个对象是一个很大的数字。

(BK = BitKeeper)

如今,内核甚至不是最大的 git 项目,甚至内核也有大约 220k 的修订版(比 BK 树大得多),我们正在接近 200 万个对象。那时,七个十六进制数字对于其中的许多人来说仍然是唯一的,但是当我们 仅谈论对象数量和哈希大小之间的两个数量级差异,在截断的哈希值中发生冲突。它不再接近于不切实际——它一直在发生。

我们都应该增加不切实际的小默认缩写,添加一种方法让人们在 git 配置文件中设置他们自己的每个项目的默认默认值。

【讨论】:

  • 我很好奇,最大的git项目是什么?或者至少,绝对庞大的 git 存储库有哪些最好的例子?
  • @GeorgeMillo 正如blogs.atlassian.com/2014/05/handle-big-repositories-git 中提到的,你有两种巨大的存储库(巨大的历史,或巨大的二进制文件)巨大的 git 存储库的一个例子是 Facebook 的:news.ycombinator.com/item?id=7648237(他们从然后到他们自己的 Mercurial 版本)
  • 您的意思是 7 个十六进制数字(28 位),而不是 7 位。
  • @ThomasJacob 谢谢。我已经相应地编辑了答案。
  • @ThomasJacob 注意:SHA1 并不总是 Git 中使用的默认哈希算法。这正在演变:stackoverflow.com/a/47838703/6309
猜你喜欢
  • 2012-03-12
  • 1970-01-01
  • 1970-01-01
  • 2011-06-26
  • 2020-05-05
  • 2017-07-14
  • 2013-09-01
  • 2015-04-07
  • 2015-02-18
相关资源
最近更新 更多