Git内部:Git如何存储修订之间的微小差异?
据我所知,一些VCS存储了版本之间的差异,因为有时候差异很小——源代码中的一行代码被更改,或者在后续版本中添加了注释。另一方面,Git为每个版本存储压缩的“快照”Git内部:Git如何存储修订之间的微小差异?,git,Git,据我所知,一些VCS存储了版本之间的差异,因为有时候差异很小——源代码中的一行代码被更改,或者在后续版本中添加了注释。另一方面,Git为每个版本存储压缩的“快照” 如果只做了一个小的更改(大文本文件中的一行),Git如何处理这个问题?它是否存储两个几乎相同的副本?我认为这是对空间的低效利用 Git使用补丁或hunks。它计算2版本之间引入的差异并存储它 存储两个几乎相同的副本?我认为这是对空间的低效利用 Git扫描您的代码(启发式),并且只存储一次差异。如果git在多个文件中找到相同的代码,它将
如果只做了一个小的更改(大文本文件中的一行),Git如何处理这个问题?它是否存储两个几乎相同的副本?我认为这是对空间的低效利用 Git使用补丁或
hunks
。它计算2版本之间引入的差异并存储它
存储两个几乎相同的副本?我认为这是对空间的低效利用
Git扫描您的代码(启发式),并且只存储一次差异。如果git在多个文件中找到相同的代码,它将为类似的代码生成hunk
,并将指向它的指针存储在原始位置
让它变得简单-它比下面解释的要复杂得多,让它变得简单,这样你就可以更容易地理解它
扫描代码后,git搜索来自上一次提交的更改,如果发现更改,git将旧更改拆分为一个大块如果您在文件的中间添加了代码,那么它将被拆分为3个大块(顶部=旧代码,中间-新代码,底部-旧代码),现在您将有3个大块。下次git扫描你的代码时,他将使用这3个大块头来搜索更改 例如:假设您有一组文件,每个文件的顶部都有许可协议,这在您的所有文件中都是相同的。
Git将扫描文件,第一个大块将作为补丁存储,Git将在所有其他文件上放置一个指向该大块的指针 这种方式git以一种非常有效的方式存储信息
如果您想查看it操作,请使用
git add-p
并选择s
进行拆分
修补程序本身看起来像:
如上所述,hunk是一个与众不同的人,这里有一点关于这一点。
hunk
是一个与diff相关的术语,下面是git如何直观地显示它(补丁):
该格式以与上下文格式相同的两行标题开始,但原始文件前面有--
,新文件前面有++
下面是一个或多个变更块,其中包含文件中的行差异。未更改的上下文行前面有空格字符,添加行前面有加号,删除行前面有减号
更多信息:
git存储实际提交文件的方式在存储库的整个生命周期中都会有所不同,但让我们从基础开始 当您将一个文件提交到存储库(即新文件)时,将生成该文件的完整副本。SHA1是根据其内容计算的,这是该文件的“对象id” 您可以在
.git\objects\SH\A1 hash
SH\A1散列
我用我的方式指示SHA1的前两个字符用作文件夹名,其余38个字符用作该目录中的文件名
然后修改该文件,将其添加到索引中,然后提交
这将再次存储为一个全新的文件,其索引方式与上述完全相同
这很容易测试,但请记住,无论何时进行更改1个文件的提交,都会得到3个git对象:
- 文件的新版本
- “树”对象,指示索引中每个文件的哪个版本用于此特定提交
- 提交对象,存储对其父对象和树的引用
git cat file-p SHA1
下面是一种测试方法:
git log
并复制提交的SHA1tree d7d68c5b2ecc58da225c953e35b0797a4805b844
author Lasse Vågsæther Karlsen <lassevagsaether.karlsen@visma.com> 1491986419 +0200
committer Lasse Vågsæther Karlsen <lassevagsaether.karlsen@visma.com> 1491986419 +0200
First copy
100644 blob 3b5d02884e6a17f20ed7938bf9e534f1bd0d195e Temp.7z
这告诉您索引包含一个文件(1行),文件名为Temp.7z
,并告诉您其SHA1 id。复制此idgit cat file-p SHA1,您将看到您添加的文件的内容