Git设计决定存储内容而不是差异

时间:2009-09-21 04:23:16

标签: git

有没有人可以告诉我为什么git开发人员做出设计决定来存储文件内容(blob),所以当内容发生变化时,需要创建一个新的blob?

我认为subversion存储修订而不是内容,所以当内容发生变化时,它只是跟踪两者之间的差异。难道git也不是这样做的吗?存储内容而不是修改有什么好处?

3 个答案:

答案 0 :(得分:11)

我找不到快速谷歌的答案,但我相信它归结为一个简单的“无关紧要因为磁盘空间便宜”。

在源代码管理工具中存储修订版很棘手。如果您只存储先前版本与当前版本之间的差异,则最终会出现两个问题:

  1. 返回最新版本(常见情况)需要最多的工作,因为代码需要通过将每个修订版本组合在一起来组装该修订版本。
  2. 对一个修订版的任何错误(例如,磁盘故障)都会破坏对以后每个版本的访问。
  3. 我相信大多数现代VCS实际上存储了最新版本(出于性能原因),如果使用差异,则会使用它们来回溯,而不是转发。

答案 1 :(得分:5)

解决此(及相关)问题的文章是Repository Formats Matter。这是影响我几年前搬到Git的决定的文章之一。这是一段摘录:

  

鉴于这一论点,我应该清楚我认为git的存储库结构比其他存储库结构更好,至少对于X.org的使用模型而言。它似乎有几个有趣的属性:

     
      
  1. 永远不会修改包含对象数据的文件。编写完成后,每个文件都是从那时起的只读文件。

  2.   
  3. 压缩是离线完成的,可以延迟到主要对象保存到备份媒体之后。此方法提供比任何增量方法更好的压缩,允许在磁盘上重新排序数据以匹配使用模式。

  4.   
  5. 对象数据本身就是自我检查;您无法在第一次引用对象时修改存储库中的对象并转义检测。

  6.   

答案 2 :(得分:4)

让我澄清你的错误观念:

  

有谁能告诉我为什么git开发人员做出设计决定来存储文件内容(blob),所以当内容发生变化时,需要创建一个新的blob?

(初始)Git设计的相当好的解释可以在Tom Preston-Werner的The Git Parable文章中找到(除了与Greg Hewgill answer链接的文章)。

背后的想法是,在新版本中通常(在足够大的项目中)只有项目中大量文件中的少数文件发生变化,因此只存储不同版本的文件内容可以节省空间。这与 Subversion在其“廉价拷贝”技术中使用相同的想法(它使用硬链接,IIRC)。

此外,文件的内容是zlib(deflate)压缩(或者更确切地说,git存储库数据库中的每个对象都被压缩,包括comit对象)。

  

我认为Subversion存储修订而不是内容,所以当内容发生变化时,它只是跟踪两者之间的差异。难道git也不是这样做的吗?存储内容而不是修订版有什么好处?

我不明白你想在这里说什么。

如果存储差异可以节省空间,那么我想告诉你除了'松散'格式(每个blob,即文件的每个(不同)内容存储在单独的文件内{ {1}})也有'压缩'格式,其中许多对象使用来自LibXDiff库的二进制增量以deltaified形式存储。

这种格式是为网络传输而创建的(大磁盘空间可能很便宜,但带宽不是这样),并且也适用于磁盘格式。这种格式非常有效,即使不是最有效的版本控制系统格式也是一种更有效的格式,使得git存储库更小或者是不同版本控制系统中最小的存储库之一。根据具体情况,git存储库的完整克隆(包含完整历史记录)可能小于等效的Subversion checkout (其中包含pristine更改的额外副本,以便.git并且svn diff无需网络传输即可以合理的速度工作。

这种设计('松散'和'打包'格式)具有非常高效的打包优势,但缺点是必须使用“svn status”手动重新打包(不是为了磁盘空间,而是为了性能) - 磁盘I / O);现在大多数git命令在需要时(安全地)重新打包存储库。