如果两个Git提交具有相同的SHA-1哈希,会发生什么?

时间:2015-09-16 22:12:09

标签: git

让我用这个作为前缀,说我知道发生这种情况的极小的可能性。我知道制造它或多或少是不可能的,极其不太可能“在野外”发生。这只是关于Git内部的假设问题。

所以,这是我的问题:如果两个Git提交哈希相同,会发生什么?对于初学者:

  • 提交会成功吗?
  • 以后可以作为一个独立的头检查出来吗?
  • 后续提交是否可行?

2 个答案:

答案 0 :(得分:4)

我的旧答案" How would git handle a SHA-1 collision on a blob?"仍然适用,即使是提交而不是blob 正如torek提到in the comments,git只是将所有内容都视为"对象",每个都有自己的SHA1。

https://git-scm.com/book/en/v2/book/10-git-internals/images/data-model-4.png

(图片来自Git Internals - Git ReferencesProGit Book v2

虽然提交可能不会成功(git-commit-tree.c中有几个检查),但您还必须考虑在repos A中创建两个具有相同SHA1(以及某种程度上不同内容)的提交的情况和B ......并且回购A正在获取回购B! Commit 8685da4 (March 2007, git 1.5.1)处理了这一点,并且取消将失败 Commit 0e8189e (Oct. 2008, git 1.6.1)确实提到了 index V2

  

SHA1引用被破坏的几率实际上与另一个具有相同大小的对象的SHA1匹配(delta头存储要应用的基础对象的预期大小)几乎为零。

解包对象时仍会实现打包对象CRC检查。

Git code mentioned belowfinalize_object_file() function,而a blame显示最近没有修改,大部分代码可追溯到Git(2005)的开头:没有创建新的提交。

答案 1 :(得分:1)

根据源代码(存在于git v2.17中),如果提交导致已经存在的sha1,那么Linux上会发生这种情况(对于其他操作系统,它可能会有所不同)。

  

提交会成功吗?

是和否:fc1395f4a491a7da46a446233531005634eb979d命令将返回,如果成功,但不会创建新的提交对象。

  

以后可以作为一个独立的头检查出来吗?

没有

参考: 文件sha1-file.c(commit int finalize_object_file(const char *tmpfile, const char *filename) { int ret = 0; if (object_creation_mode == OBJECT_CREATION_USES_RENAMES) goto try_rename; else if (link(tmpfile, filename)) ret = errno; /* * Coda hack - coda doesn't like cross-directory links, * ... */ if (ret && ret != EEXIST) { try_rename: if (!rename(tmpfile, filename)) goto out; ret = errno; } unlink_or_warn(tmpfile); if (ret) { if (ret != EEXIST) { return error_errno("unable to write sha1 filename %s", filename); } /* FIXME!!! Collision check here ? */ } out: if (adjust_shared_perm(filename)) return error("unable to set permission to '%s'", filename); return 0; }

return 0

链接因EEXIST失败,临时文件被删除,代码一直持续到adjust_shared_perm()(通过FIXME,以及<h1> Hotel kamer reservering </h1> <br><br> <form method="POST"> <input name="roomtype" type="radio" checked="checked" value="éénpersoonskamer">éénpersoonskamer <br><br> <input name="roomtype" type="radio" value="tweepersoonskamer">tweepersoonskamer <br><br> <input name="food[]" type="checkbox" value="ontbijt">ontbijt <br><br><br> <input name="food[]" type="checkbox" value="lunch">lunch <br><br><br> <input name="food[]" type="checkbox" value="diner">diner <br><br><br> <input name="submit" type="submit"> </form> <?php if(!empty($_POST['submit'])) { echo "roomtype: " . $_POST['roomtype'] . "<br>"; $food = $_POST['food']; foreach ($food AS $k => $v) { echo "Food $k = $v<br>"; } } ?> 没有理由失败)。