有没有人可以告诉我为什么git开发人员做出设计决定来存储文件内容(blob),所以当内容发生变化时,需要创建一个新的blob?
我认为subversion存储修订而不是内容,所以当内容发生变化时,它只是跟踪两者之间的差异。难道git也不是这样做的吗?存储内容而不是修改有什么好处?
答案 0 :(得分:11)
我找不到快速谷歌的答案,但我相信它归结为一个简单的“无关紧要因为磁盘空间便宜”。
在源代码管理工具中存储修订版很棘手。如果您只存储先前版本与当前版本之间的差异,则最终会出现两个问题:
我相信大多数现代VCS实际上存储了最新版本(出于性能原因),如果使用差异,则会使用它们来回溯,而不是转发。
答案 1 :(得分:5)
解决此(及相关)问题的文章是Repository Formats Matter。这是影响我几年前搬到Git的决定的文章之一。这是一段摘录:
鉴于这一论点,我应该清楚我认为git的存储库结构比其他存储库结构更好,至少对于X.org的使用模型而言。它似乎有几个有趣的属性:
永远不会修改包含对象数据的文件。编写完成后,每个文件都是从那时起的只读文件。
压缩是离线完成的,可以延迟到主要对象保存到备份媒体之后。此方法提供比任何增量方法更好的压缩,允许在磁盘上重新排序数据以匹配使用模式。
- 醇>
对象数据本身就是自我检查;您无法在第一次引用对象时修改存储库中的对象并转义检测。
答案 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命令在需要时(安全地)重新打包存储库。