有人知道Git在文件数量和文件大小方面的限制吗?
有人知道Git在文件数量和文件大小方面的限制吗?
这条来自林纳斯本人的消息可以帮助你解决一些其他限制
请看我其他答案中的更多内容:Git的限制在于每个仓库必须代表一个“一致的文件集”,即整个系统本身(你不能标记“仓库的一部分”)。[...] CVS,即它实际上几乎完全是面向“一次一个文件”的模型。
这很好,因为您可以有数百万个文件,然后仅检查其中的一些文件-您甚至不会看到其他999,995个文件的影响。
Git从根本上来说永远不会真正地只关注部分内容。即使您将事情限制在某种程度上(即仅检出一部分,或者历史记录仅返回一点),Git最终仍然始终关心整个内容,并携带着这些知识。
因此,如果您强制Git将所有内容视为一个巨大的存储库,则Git的扩展性非常差。我认为那部分真的无法修复,尽管我们可能可以对其进行改进。
是的,然后还有“大文件”问题。我真的不知道该怎么处理大文件。我知道我们做得不好。
如果想更深入地了解git限制,请参考 "git with large files" (提到了git-lfs: 一种将大文件存储在git仓库外的解决方案。GitHub,2015年4月)
影响git仓库的三个问题:
一篇较新的帖子(2015年2月)说明了Git仓库的限制因素:
从中央服务器克隆几个同时的副本是否也会减慢其他用户的并发操作?
在克隆时服务器没有锁,因此理论上克隆不会影响其他操作。但是克隆可能会使用大量内存(除非您打开可达性位图功能,这样可以节省大量 CPU 使用率)。
'
git pull
'会很慢吗?如果我们排除服务器端,那么你的树大小是主要因素,但你的 25k 个文件应该没问题(Linux 有 48k 个文件)。
'
git push
'呢?这个不受您的仓库历史记录有多深或者树有多宽的影响,因此应该很快。
啊,引用的第三个参考文献中可能会影响
git-push
和git-pull
的引用数量。
我认为 Stefan 在这方面更加专业。'
git commit
'呢?(在参考文献3中列为慢速操作。) 'git status
'呢?(虽然我没有看到它在参考文献3中。) (还有git-add
)同样,取决于您的树大小。在您的仓库大小下,我认为您不需要担心。
一些操作可能看起来不是每天都使用的,但如果它们被 GitLab/Stash/GitHub 等 Web 前端频繁调用,则可能成为瓶颈。(例如,'
git branch --contains
' 在大量分支时似乎受到严重影响。)当文件被频繁修改时,
git-blame
可能会很慢。
没有真正的限制 - 一切都使用160位的名称来命名。文件的大小必须能够用64位数字表示,因此也没有真正的限制。
但是有一个实际的限制。我有一个存储了880,000个以上文件、大约8GB的存储库,git gc需要一段时间。工作树相当大,因此检查整个工作目录的操作需要相当长的时间。不过这个存储库只用于数据存储,所以只是一堆自动化工具在处理它。从存储库中拉取更改比使用rsync同步相同的数据要快得多。
%find . -type f | wc -l
791887
%time git add .
git add . 6.48s user 13.53s system 55% cpu 36.121 total
%time git status
# On branch master
nothing to commit (working directory clean)
git status 0.00s user 0.01s system 0% cpu 47.169 total
%du -sh .
29G .
%cd .git
%du -sh .
7.9G .
.git
目录还要大呢?我天真地以为 .git
包含了工作目录的副本和历史记录,所以它一定更大。谁能指导我了解这些大小是如何相关的资源? - bluenote10.git
目录中的内容是经过压缩的。因此,相对较少提交的存储库可能具有比未压缩的工作目录更小的压缩历史记录。我的经验表明,在实践中,对于 C++ 代码,整个历史记录通常与工作目录的大小大致相同。 - prapin致命错误:内存不足,malloc失败
更多细节请查看此处
更新于3/2/11:在Windows 7 x64上使用Tortoise Git时也遇到了类似问题。大量内存被占用,系统响应非常缓慢。
这取决于您的意思是什么。如果您有很多大文件,它可能会变得非常缓慢。如果您有很多文件,扫描速度也会变慢。
但是,模型并没有固有的限制。您当然可以使用不当,感到痛苦。
git status
如何快速找到更改文件的方式--通过inode通知或其他方式。更新:来自@VonC, below的信息:git --version
显示git version 2.34.1
。
git init
瞬间完成。
time git add -A
花了17分37.621秒。
time git commit
大约花了11分钟,因为它显然需要运行git gc
来打包文件。
我建议使用time git commit -m "Add all files"
,这样就不会让你的文本编辑器打开一个有2.1M行的文件。我已经按照这里的指示将Sublime Text设置为我的git编辑器,并且它处理得还可以,但是打开文件需要几秒钟的时间,而且没有正常情况下的语法高亮。
当我的提交编辑器仍然打开并且我正在输入提交消息时,我收到了这个GUI弹窗:
文本内容:
您的系统未配置足够的inotify监视器,这意味着我们将无法跟踪文件系统的更改,某些功能可能无法正常工作。我们可以尝试将限制从65536增加到524288。这需要root权限。
错误:授权失败
所以,我点击了“更改限制”并输入了我的root密码。
这似乎表明,如果您的存储库有超过524288(约500k)个文件和文件夹,那么git无法保证使用git status
检测到更改的文件,对吗?
在我的提交编辑器关闭后,这是我的计算机在提交和打包数据时的情况:
请注意,我的基线RAM使用量大约为17 GB,所以我猜只有大约10 GB的RAM使用量来自git gc
。实际上,“眼测”下面的内存图显示,我的RAM使用量从提交之前的大约25%上升到提交期间的大约53%,总使用量为53-23 = 28% x 67.1 GB = 18.79 GB左右的RAM使用量。
这是有道理的,因为事后看,我发现我的主要pack文件大小为10.2 GB,位置在这里:.git/objects/pack/pack-0eef596af0bd00e16a9ba77058e574c23280e28f.pack
。因此,从逻辑上来说,加载该文件到RAM并处理它进行打包至少需要这么多的内存。
这是git在屏幕上打印的内容:
$ time git commit
正在后台自动打包存储库以获得最佳性能。
有关手动维护,请参阅“git help gc”。
完成需要大约11分钟。
time git status
现在是干净的,但是需要大约2~3秒钟。有时会打印出正常的消息,例如:
$ time git status
在分支main上
没有要提交的内容,工作树干净
<p>这结束了我在git中进行的真实数据测试。我建议您坚持使用< 500k个文件。尺寸方面,我不知道。也许你可以用50 GB、2 TB或10 TB来应对,只要你的文件数量接近500k个文件或更少。</p>
<h2>进一步操作:</h2>
<h3>1. 通过我的11 GB <code>.git</code>目录给某人我的107 GB存储库</h3>
<p>现在,git已将我2.1M个文件的107 GB压缩成一个11 GB的<code>.git</code>目录,我可以轻松地重新创建或共享这个<code>.git</code>目录给我的同事,以便将整个存储库交给他们!不要复制整个123 GB的存储库目录。相反,如果您的存储库名为<code>my_repo</code>,只需在外部驱动器上创建一个空的<code>my_repo</code>目录,将<code>.git</code>目录复制到其中,然后将其交给同事。他们将其复制到他们的计算机上,然后像这样重新实例化存储库中的整个工作树:</p>
<pre class="lang-bash prettyprint-override"><code>cd path/to/my_repo
# Unpack the whole working tree from the compressed .git dir.
# - WARNING: this permanently erases any changes not committed, so you better
# not have any uncommitted changes lying around when using `--hard`!
time git reset --hard
time git reset --hard
解压命令花费了7分32秒,而git status
现在是干净的。.git
目录被压缩在一个.tar.xz
文件中,名为my_repo.tar.xz
,那么指令可能会变成这样:
如何从只包含11 GB .git
目录的my_repo.tar.xz
文件中恢复整个107 GB的my_repo
仓库:
# Extract the archive (which just contains a .git dir)
mkdir -p my_repo
time tar -xf my_repo.tar.xz --directory my_repo
# In a **separate** terminal, watch the extraction progress by watching the
# output folder grow up to ~11 GB with:
watch -n 1 'du -sh my_repo'
# Now, have git unpack the entire repo
cd my_repo
time git status | wc -l # Takes ~4 seconds on a high-end machine, and shows
# that there are 1926587 files to recover.
time git reset --hard # Will unpack the entire repo from the .git dir!;
# takes about 8 minutes on a high-end machine.
meld
比较复制文件夹修订版本之间的变化按照以下步骤进行操作:
meld path/to/code_dir_rev1 path/to/code_dir_rev2
git status
和git add -A
会不会有时候错过我的更改? - Gabriel Staplesinotify
监视器的警告时,这是因为您的存储库中的文件数量超过了当前的inotify
限制。增加限制可以让inotify
(以及Git)跟踪更多的文件。然而,这并不意味着Git在超过此限制后将无法工作:如果达到限制,git status
或git add -A
不会“错过”更改。相反,这些操作可能会变得较慢,因为Git需要手动检查更改,而不是从inotify
机制获取更新。 - VonC'status -uno'
的信息,这是我现在有时候在git status
中看到的(在我的回答中搜索一下)。你以前见过这个吗?这是因为我超出了inotify watches
的限制吗? - Gabriel Staples我发现在存储大量文件(350k+)时使用版本库。是的,存储。哈哈。
$ time git add .
git add . 333.67s user 244.26s system 14% cpu 1:06:48.63 total
我认为尽量避免将大文件提交到代码库中是一个好的做法(例如,数据库转储最好放在其他地方),但如果考虑到内核在其代码库中的大小,那么你可以预期与任何比它更小且不太复杂的东西一起轻松工作。
我有大量的数据存储在我的仓库中,这些数据以单独的JSON片段形式存储。大约有75,000个文件分布在几个目录下,并且不会对性能造成太大影响。
第一次检查它们时,显然会有点慢。