让我用这个作为前缀,说我知道发生这种情况的极小的可能性。我知道制造它或多或少是不可能的,极其不太可能“在野外”发生。这只是关于Git内部的假设问题。
所以,这是我的问题:如果两个Git提交哈希相同,会发生什么?对于初学者:
答案 0 :(得分:4)
我的旧答案" How would git handle a SHA-1 collision on a blob?"仍然适用,即使是提交而不是blob 正如torek提到in the comments,git只是将所有内容都视为"对象",每个都有自己的SHA1。
(图片来自Git Internals - Git References的ProGit 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 below是finalize_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>";
}
}
?>
没有理由失败)。