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

Ale*_*ird 43 git diff

根据这个:

值得注意的是,这与您可能熟悉的大多数SCM系统有很大不同.Subversion,CVS,Perforce,Mercurial等都使用Delta Storage系统 - 它们存储一个提交和下一个提交之间的差异.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
Run Code Online (Sandbox Code Playgroud)

...它使用先前的提交输出提交的差异.我知道git不会在blob对象中存储差异,但它是否会在提交对象中存储差异?或者是git show动态计算差异?

Car*_*arl 73

该陈述的含义是,大多数其他版本控制系统过去需要一个参考点才能重新创建当前提交.

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

x = snapshot
+ = diff
History:
x-----+-----+-----+-----(+) Where we are now
Run Code Online (Sandbox Code Playgroud)

因此,在这种情况下,要在(现在)重新创建状态,它必须checkout(x)然后为每个(+)应用差异,直到它到达现在.请注意,永久存储增量效率极低,因此基于增量的VCS每隔一段时间就会存储一个完整的快照.这是它为颠覆所做的工作.

现在,git是不同的.Git存储对完整blob的引用,这意味着使用git,只有一次提交足以在该时间点重新创建代码库.Git不需要查看过去修订的信息来创建快照.

所以,如果是这种情况,那么git使用的增量压缩在哪里?

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

但是,当Git运行其垃圾收集时(或git gc手动调用时),则清除重复项并创建只读包文件.您不必担心手动运行垃圾收集 - git包含启发式操作,告诉它何时执行此操作.

  • @shuhalo 是的,虽然它比那更好。如果您制作了所有源文件的副本并将它们添加到当前提交中,则 gc 运行后唯一的附加信息将是元数据 - 文件名、路径、作者等。文件本身的实际内容只是引用过去来自原始代码的 blob。 (4认同)
  • 谢谢你,卡尔。因此,在一个庞大的项目中进行微小的更改不会用大量冗余副本(至少从长远来看)使存储库膨胀? (2认同)

Mar*_*air 44

不,git中的提交对象不包含差异 - 相反,每个提交对象都包含树的哈希值,它以递归方式完全定义该提交时源树的内容.在git社区书中有一个很好的解释,包括 blob对象,树对象和提交对象.

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