根据我的理解,文件夹.git包含所有blob
和commit
对象。所以它总是比工作目录中的文件大。
怎么会发生这种事?是不是因为存储库包含很多小文件(小于 block 大小),Git 会压缩它们?
更详细的解释是什么?
实际上,让我困惑的存储库是 CocoaPods master存储库。该存储库用于存储 iOS 库规范。当库的新版本发布时,a new file已添加(不编辑现有的)到此存储库。新添加的规范通常与之前的版本非常相似,也许只是版本发生了变化。这将向存储库添加至少三个对象:一个 blob、一棵树和一个提交。
使用du -d 1 h
,大小为
1.1G ./Specs
729M ./.git
最佳答案
So it always is larger than the file in the working directory.
不。
为了理解,您需要了解 Git 如何存储其数据。 Git 使用启发式方法来查找代码中的相似部分。换句话说,当 Git 找到相同的内容(整个文件或部分文件)时,它不会存储两次,而是存储一次并使用指针指向第一次出现的内容。这就是所谓的帅哥。
每当您执行git add
时,Git都会抓取内容,“设置” block 并稍后将它们存储在包文件中。回到正轨,当您执行 git add 时,Git 会抓取内容,并使用 sha1sum 对其进行哈希处理。 、 hash-object 等,将其压缩并将其存储在您的 .git/objects 文件夹中。
文件的“真实”内容(一旦 Git 稍后将其打包)只是称为“ block ”的较小块,Git 知道如何将它们索引到原始文件中。
什么是帅哥?
Hunks 是补丁文件。您可以在执行 git add -p 时看到它们,然后,如果您对文件中的多个位置进行了多项更改,请选择 s ,您就会看到它们。
这些是您可以在 add -p
中执行的选项:
y - stage this hunk
n - do not stage this hunk
q - quit, do not stage this hunk nor any of the remaining ones
a - stage this and all the remaining hunks in the file
d - do not stage this hunk nor any of the remaining hunks in the file
g - select a hunk to go to
/ - search for a hunk matching the given regex
j - leave this hunk undecided, see next undecided hunk
J - leave this hunk undecided, see next hunk
k - leave this hunk undecided, see previous undecided hunk
K - leave this hunk undecided, see the previous hunk
s - split the current hunk into smaller hunks
e - manually edit the current hunk
? - print help
一旦您使用s
,它将选择可以被视为独立更改的代码块。如果您想进一步拆分它,则必须使用 e
编辑该 block ,然后将其添加回舞台区域。
Git 存储“补丁”,即更改的增量,但 Git 在其之上添加了一些其他“层”。一旦它“看到”相同的内容(这是使用启发式完成的),它就会重用相同的内容,并在指向旧内容的同时仅添加"new"更改。
随后,Git 获取内容并使用 ZIP 对其进行打包。
关于git - 为什么文件夹 '.git'的大小可以小于工作目录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53681343/