3

显然 Mercurial 为每个变更分配了一个全局变更集 ID。他们如何确保这是独一无二的?

4

2 回答 2

8

正如 Zach 所说,变更集 ID 是使用SHA-1 哈希函数计算的。这是加密安全散列函数的示例。加密散列函数采用任意长度的输入字符串,并从该字符串生成固定长度的摘要。在 SHA-1 的情况下,输出长度固定为 160 位,其中 Mercurial 默认只显示前 48 位(12 个十六进制数字)。

密码散列函数的特性是很难找到两个不同的输入产生相同的输出,也就是说,很难找到x != y这样的字符串H(x) == H(y)。这称为抗碰撞性。

由于 Mercurial 使用 SHA-1 函数来计算变更集 ID,因此对于相同的输入(相同的更改、相同的提交者名称和日期),您将获得相同的变更集 ID。但是,如果您使用不同的输入 ( x != y),则由于碰撞阻力,您将获得不同的输出(变更集 ID)。

换句话说,如果您没有为不同的输入获得不同的变更集 ID,那么您已经发现了 SHA-1 的冲突!到目前为止,还没有人发现 SHA-1 的碰撞,所以这将是一个重大发现。


更详细地说,SHA-1 哈希函数在 Mercurial 中以递归方式使用。每个变更集哈希通过连接计算:

  • 清单 ID
  • 提交用户名
  • 提交日期
  • 受影响的文件
  • 提交消息
  • 第一个父变更集 ID
  • 第二个父变更集 ID

然后在所有这些上运行 SHA-1(参见changelog.pyrevlog.py)。因为哈希函数是递归使用的,所以变更集哈希将修复整个历史,一直回到变更集图中的根。

这也意味着,如果您Hello World!使用相同的提交消息同时将该行添加到两个不同的项目中,您将不会获得相同的变更集 ID——当它们的历史不同(不同的父变更集)时,两个新的变更集将获得不同的 ID .

于 2010-08-25T08:02:05.180 回答
5

Mercurial 的变更集 ID 是每个变更集的“清单”的 SHA-1 哈希。它只打印全局 ID 的前十个十六进制数字,但它使用完整的 SHA-1 进行内部操作。没有实际保证它们是唯一的,但对于实际目的来说这不太可能。

请参阅此处了解详细信息

于 2010-08-25T01:12:52.763 回答