为了实验,我们假设你的git log
标识了以下提交
commit 16bc8486fb34cf9a6faf0f7df606ae72ad9ea438 // added 2nd file
commit 9188f9a25b045f130b08888bc3f638099fa7f212 // initial commit
提交后,.git/refs/heads/master
指向16bc8486fb34cf9a6faf0f7df606ae72ad9ea438。
让我们说,在此之后,我手动编辑.git/refs/heads/master
文件以指向9188f9a25b045f130b08888bc3f638099fa7f212
此时,git status识别出一个新的未提交文件需要引起注意。这是我第二次提交之前处理的文件。
如果我提交了它.. git log
现在显示
commit b317f67686f9e6ab1eaabf47073b401d677205d5 // 2nd file committed for the 2nd time
commit 9188f9a25b045f130b08888bc3f638099fa7f212 // initial commit
问题1:
你会注意到我第一次提交第二个文件和现在之间的SHA
哈希值是不同的。这是为什么?文件的内容没有改变,它仍然是完全相同的文件。
问题2
此时,原来的第二次提交发生了什么?当我执行git show 16bc8486
时,它会显示此提交。但它并未显示在git log
历史记录中。
答案 0 :(得分:14)
问题1:因为哈希是在考虑到所有内容的情况下生成的,包括提交元数据(其本身包含日期和时间)。
问题2:git log
显示当前分支的日志。提交16bc8486
不属于它。据我所知(我不完全确定)垃圾收集器迟早会把它带走,如果它发现它没有引用它(git gc --help
)..
答案 1 :(得分:6)
如果您具有相同的内容(即使文件名已更改),每种文件 blob 的sha1值在两种情况下都是相同的。
同样,如果文件blob的树的sha1值具有相同的文件名,则它们将是相同的。
然而,在最顶层,我们有提交,它将包含前一次提交,顶级树,作者和提交者的未更改链接,但正如KingCrunch所说,作者和提交者日期将是不同,因此提交sha1的sha1将是不同的。
如果您故意使用环境变量设置作者和提交者日期,则可以使它们相同,以便它们保持不变。
答案 2 :(得分:2)
SHA1是根据差异和来自此提交的所有元数据计算的(包括作者和提交者,时间戳和各种其他数据)。
对于您的第二个问题,数据提交仍然存在,但不再是任何实时分支的一部分。有时git会运行垃圾收集,其中实际上会删除各种已删除的东西。您会注意到,一旦您使用git gc
手动运行它,未引用的提交将会消失,甚至无法通过git show访问。