分配mercurial全局变更集ID

时间:2010-08-25 01:04:20

标签: mercurial dvcs sha1 changeset

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

2 个答案:

答案 0 :(得分:8)

正如Zach所说,变更集ID是使用SHA-1 hash function计算的。这是加密安全散列函数的示例。加密散列函数接受任意长度的输入字符串,并从该字符串生成固定长度的摘要。在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)。因为散列函数是递归使用的,所以changeset hash会将整个历史记录一直修复回变更集图中的根。

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

答案 1 :(得分:5)

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

See here for gory details