git是否在提交对象中存储差异信息?

git是否在提交对象中存储差异信息?,git,diff,Git,Diff,根据: 需要注意的是,这与大多数SCM非常不同 您可能熟悉的系统。Subversion、CVS、Perforce、, Mercurial等都使用Delta存储系统—它们存储 一次提交和下一次提交之间的差异。Git不行 它存储项目中所有文件的快照 每次提交时,在这个树结构中都是这样。这是一个 使用Git时需要理解的非常重要的概念 然而,当我运行git show$SHA1ofCommitObject时, commit 4405aa474fff8247607d0bf599e054173da84113

根据:

需要注意的是,这与大多数SCM非常不同 您可能熟悉的系统。Subversion、CVS、Perforce、, Mercurial等都使用Delta存储系统—它们存储 一次提交和下一次提交之间的差异。Git不行 它存储项目中所有文件的快照 每次提交时,在这个树结构中都是这样。这是一个 使用Git时需要理解的非常重要的概念

然而,当我运行git show$SHA1ofCommitObject时,

commit 4405aa474fff8247607d0bf599e054173da84113
Author: Joe Smoe <joe.smoe@example.com>
Date:   Tue May 1 08:48:21 2012 -0500

    First commit

diff --git a/index.html b/index.html
new file mode 100644
index 0000000..de8b69b
--- /dev/null
+++ b/index.html
@@ -0,0 +1 @@
+<h1>Hello World!</h1>
diff --git a/interests/chess.html b/interests/chess.html
new file mode 100644
index 0000000..e5be7dd
--- /dev/null
+++ b/interests/chess.html
@@ -0,0 +1 @@
+Did you see on Slashdot that King's Gambit accepted is solved! <a href="http://game
commit 4405aa474fff8247607d0bf599e054173da84113
作者:乔·斯莫
日期:2012年5月1日星期二08:48:21-0500
第一次提交
diff——git a/index.html b/index.html
新文件模式100644
索引0000000..de8b69b
---/dev/null
+++b/index.html
@@ -0,0 +1 @@
+你好,世界!
diff--git a/interests/chess.html b/interests/chess.html
新文件模式100644
索引0000000..e5be7dd
---/dev/null
+++b/interests/chess.html
@@ -0,0 +1 @@

+你有没有在Slashdot上看到国王的策略已经解决了 不,git中的提交对象不包含diff-相反,每个提交对象都包含一个树的散列,它递归地、完整地定义了提交时源树的内容。blob对象、树对象和提交对象中有很多内容


git的工具显示给您的所有差异都是根据文件的完整内容按需计算的。

这句话的意思是,大多数其他版本控制系统在过去都需要一个参考点才能重新创建当前提交

例如,在过去的某个时候,基于差异的VCS(版本控制系统)会存储完整的快照:

x = snapshot
+ = diff
History:
x-----+-----+-----+-----(+) Where we are now
因此,在这种情况下,要在(现在)重新创建状态,它必须签出(x),然后对每个(+)应用差异,直到现在为止。请注意,永久存储增量将极为低效,因此,基于增量的VCSE通常会存储完整的快照

现在,git不同了。Git存储对完整blob的引用,这意味着使用Git,只有一次提交就足以在该时间点重新创建代码库。Git不需要从过去的版本中查找信息来创建快照

如果是这样的话,那么git使用的增量压缩在哪里呢

好吧,这只是一个压缩概念——如果只改变了很小的数量,那么将相同的信息存储两次是没有意义的。因此,表示已更改的内容,但存储对它的引用,这样它所属的提交(实际上是一个引用树)仍然可以在不查看过去提交的情况下重新创建。不过,问题是Git不会在每次提交后立即执行此操作,而是在垃圾收集运行时执行此操作。所以,如果git没有运行垃圾收集,您可以在索引中看到内容非常相似的对象


但是,当Git运行其垃圾收集时(或者当您手动调用
Git gc
时),重复项将被清除,并创建一个只读包文件。您不必担心手动运行垃圾收集—git包含启发法,可以告诉它何时进行垃圾收集。

旁注:git确实对对象进行增量压缩,但这只是为了压缩。人们有时会误解为Git存储差异。这里有一些关于这种格式的文档:(请记住,它记录的对象之间的增量只是它发现的相似的数据点;它们不一定是同一文件的连续版本,尽管它们可能是。当然,这些增量不是逐行差异。)更新Jefromi的相关链接:谢谢你,Carl。因此,在一个大型项目中提交微小的更改不会使存储库中增加大量冗余副本(至少从长远来看)?@shuhalo说得对,尽管它甚至比这更好。如果您制作了所有源文件的副本并将其添加到当前提交中,则gc运行后唯一的附加信息将是元数据—文件名、路径、作者等。文件本身的实际内容只是指过去源于原始代码的blob。很抱歉,我不理解您的措辞。你能不能编辑一下:“嗯,这只是一个压缩概念——如果只改变了很小的数量,那么将相同的信息存储两次是没有意义的。因此,表示发生了什么变化‘你是说如果在一个10k行文件上,如果我添加了一个字符,那么就不会生成新的哈希吗?!这对我来说太不清楚了