Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Git 提交的SHA-1是否仅基于树的内容计算?_Git_Sha - Fatal编程技术网

Git 提交的SHA-1是否仅基于树的内容计算?

Git 提交的SHA-1是否仅基于树的内容计算?,git,sha,Git,Sha,为了便于实验,假设您的git日志标识了以下提交 commit 16bc8486fb34cf9a6faf0f7df606ae72ad9ea438 // added 2nd file commit 9188f9a25b045f130b08888bc3f638099fa7f212 // initial commit 提交后,.git/refs/heads/master指向16bc8486fb34cf9a6faf0f7df606ae72ad9ea438 比方说,在此之后,我手动编辑.git/ref

为了便于实验,假设您的
git日志
标识了以下提交

commit 16bc8486fb34cf9a6faf0f7df606ae72ad9ea438  // added 2nd file
commit 9188f9a25b045f130b08888bc3f638099fa7f212  // initial commit
提交后,
.git/refs/heads/master
指向16bc8486fb34cf9a6faf0f7df606ae72ad9ea438

比方说,在此之后,我手动编辑
.git/refs/heads/master
文件,指向9188F9A25B045F130B088BC3F638099FA7F212

此时,git status认识到需要注意一个新的未提交文件。这是我第二次提交之前处理的同一个文件

如果我真的做了<代码>git日志现在显示

commit b317f67686f9e6ab1eaabf47073b401d677205d5  // 2nd file committed for the 2nd time
commit 9188f9a25b045f130b08888bc3f638099fa7f212  // initial commit
问题1:

您会注意到,从我第一次提交第二个文件到现在,
SHA
hash是不同的。为什么呢?文件的内容没有改变,仍然是同一个文件

问题2


此时,最初的第二次提交发生了什么?当我执行git show 16bc8486时,它显示了这个提交。但是,它不会显示在git日志的历史记录中

问题1:因为哈希的生成考虑了所有因素,包括提交元数据(它本身包含日期和时间)


问题2:
git日志
显示当前分支的日志。提交
16bc8486
不是它的一部分。据我所知(我不完全确定),垃圾收集器迟早会把它拿走,如果它发现它没有任何引用(
git gc--help
)。

SHA1是根据差异和来自此提交的所有元数据(包括作者和提交者、时间戳和各种其他数据)计算出来的


对于第二个问题,数据提交仍然存在,但不再是任何活动分支的一部分。有时候git会运行一个垃圾收集,其中各种被删除的内容实际上都会被删除。您会注意到,一旦您使用
git gc
手动运行它,未引用的提交将消失,甚至无法再使用git show进行访问。

如果您具有相同的内容(即使文件名已更改),则每个文件blob的sha1值在这两种情况下都将相同

同样,如果文件blob的树具有相同的文件名,则它们的sha1值也将相同

然而,在最顶端,我们有提交,它将包含到上一次提交的未更改链接、顶层树、作者和提交人,但正如KingCrunch所说,作者和提交人日期将不同,因此提交sha1的sha1将不同


如果故意使用环境变量设置作者和提交人日期,则可以使其保持不变。

在第二季度,
git branch
仅显示此时存在的一个分支-*master。旧文件现在是哪个分支的一部分?@JAM:它不是任何分支的一部分,这就是为什么它是垃圾收集的候选对象。您可以通过在提交
git branch branch\u name commit\u hash
@Mat上显式创建一个分支来“拯救”它,如果经过一段时间,并且该哈希不可用,是否可以以某种方式恢复它?@JAM如果它没有被垃圾收集,是的-您可以使用
git fsck--unreachable
来查找所有此类提交。如果它是垃圾收集的,那么是时候测试一下你的备份了:)@JAM git确实保存了关于refs如何随时间变化的日志文件-查看
git reflog
命令和
git log-g
。垃圾收集器将日志文件考虑在内——只要对象是从日志文件引用的,它就不会修剪对象(但日志文件本身会在一段时间后自动修剪)。有趣的阅读:额外的推论;如果确实使它们相同,那么就对象存储和分支图而言,它们将是相同的。这就好像最初但完全相同的分裂从未发生过一样——它们无法区分!狩猎快乐。