2012-01-15 39 views
10

对于实验的缘故,可以说你的git log确定了以下承诺是否仅基于树的内容计算提交的SHA-1?

commit 16bc8486fb34cf9a6faf0f7df606ae72ad9ea438 // added 2nd file 
commit 9188f9a25b045f130b08888bc3f638099fa7f212 // initial commit 

承诺,.git/refs/heads/master点16bc8486fb34cf9a6faf0f7df606ae72ad9ea438后。

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

在这一点上,git的状态确认,新提交的文件是需要一定的关注。这是我第二次提交之前处理的文件。

如果我不提交它.. git log现在显示

commit b317f67686f9e6ab1eaabf47073b401d677205d5 // 2nd file committed for the 2nd time 
commit 9188f9a25b045f130b08888bc3f638099fa7f212 // initial commit 

问题1:

你会发现,SHA散列的第一次之间的不同我犯了第二个文件和现在。这是为什么?文件的内容没有改变,它仍然是一样的确切文件。

问题2

在这一点上,发生了什么事原本第二的承诺?当我做git show 16bc8486时,它显示这个提交。但它不会出现在git log的历史记录中。

+1

有趣的阅读:http://book.git-scm.com/1_the_git_object_model.html – Mat 2012-01-15 20:42:01

回答

14

问题1:因为生成的散列考虑了所有事情,包括提交元数据(本身包含日期和时间)。

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

+0

Q2上,'git branch'只显示了一个存在的分支 - * master。现在是旧文件的一部分? – JAM 2012-01-15 20:41:44

+0

@JAM:它不是任何分支的一部分,这就是为什么它是垃圾收集的候选人。您可以通过在该提交'git branch branch_name commit_hash'上显式创建一个分支来“拯救”它。 – Mat 2012-01-15 20:43:10

+0

@Mat,如果有一段时间过去了,而且这个散列不是一成不变的,是否有可能以某种方式恢复它? – JAM 2012-01-15 20:49:32

2

SHA1计算从差异和所有来自此提交的元数据(包括作者和提交者,时间戳以及各种其他数据)。

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

6

如果您拥有相同的内容(即使文件名已更改),文件Blob中每个文件的sha1值在两种情况下都是相同的。

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

然而,在最高层,我们有提交其中将包含不变链接到以前提交,顶部树,笔者和commiter,但KingCrunch说,作者和commiter日期将是不同 ,所以提交sha1的sha1将会不同。

如果您使用环境变量故意设置作者和提交者日期以使它们保持不变,那么可以使它们相同。

+0

额外的推论;如果确实使它们相同,那么就对象库和分支图而言,它们将是相同的。这就好像初始的但是完全相同的分割从未发生 - 它们是无法区分的!快乐狩猎。 – 2014-06-09 19:37:46

相关问题