改善git状态performance的方法

我有一个Linux上的NFS机器上的10 GB的回购。 第一次git状态需要36分钟,随后的git状态需要8分钟。 似乎GIT依赖于操作系统来caching文件。 只有第一个git命令像提交,包含/重新包装整个回购的状态需要很长时间才能完成一个巨大的回购。 我不确定你是否在如此庞大的回购协议中使用过git状态,但有谁遇到过这个问题?

我已经尝试过“git gc”“git clean”git repack“,但所花费的时间仍然/几乎相同。子模块或其他概念(如将分解库分解为更小的分区)是否有帮助?如果是,则最适合分解一个更大的回购有没有其他的方式来改善一个大的回购git命令的时间?

更确切地说,git依赖于lstat(2)系统调用的效率,所以调整客户端的“属性高速caching超时”可能会有诀窍。

git-update-index手册 – 基本上是git-status的手动模式 – 描述了你可以通过使用--assume-unchanged标志抑制其正常行为并手动更新已经更改的path。 每次保存文件时,甚至可以编程编辑器来取消设置此标志。

另外,如你所build议的,是减less你的结帐的大小(包装文件的大小在这里并不真正起作用)。 选项是一个稀疏的结帐,子模块,或谷歌的回购工具。

(有一个关于使用Git和NFS的邮件列表线程 ,但是它没有回答很多问题。)

在通过NFS共享的大型项目中,我也看到了这个问题。

我花了一些时间来发现可以提交给git commit和git status的标志-uno

这个标志所做的就是禁止查找未跟踪的文件。 这大大减less了nfs操作的数量。 原因是为了让git发现未跟踪的文件,它必须查看所有的子目录,所以如果你有很多子目录,这会伤害你。 通过禁用git来查找未跟踪的文件,可以消除所有这些NFS操作。

将此与core.preloadindex标志结合起来,即使在NFS上也可以获得合理的性能。

尝试git gc 。 另外, git clean 可能会有所帮助。

更新 – 不知道哪里来的投票,但git手册明确指出:

在当前版本库中运行许多内务处理任务,如压缩文件修订(以减less磁盘空间和提高性能 ),以及移除可能由之前的git add调用创build的不可达对象。

鼓励用户在每个存储库中定期运行此任务,以保持良好的磁盘空间利用率和良好的操作性能。

当git状态很慢的时候,我总是注意到运行git gc后的不同之处!

更新II – 不知道我错过了这一点,但OP已经尝试GIT GC和GIT干净。 我发誓不是原来那里,但我没有看到编辑中的任何改变。 对不起!

如果您的git repo大量使用子模块,那么可以通过编辑.git目录中的configuration文件并在任何特别大/较重的子模块上设置ignore = dirty来大大加快git状态的执行速度。 例如:

 [submodule "mysubmodule"] url = ssh://mysubmoduleURL ignore = dirty 

您将失去提醒的便利,即您可能已经忘记的任何子模块中存在未分配的更改,但仍然保留了知道子模块与主回购库不同步的主要便利性。 另外,您仍然可以将您的工作目录更改为子模块本身,并按照惯例使用其中的git状态来查看更多信息。 看到这个问题更多关于什么“脏”的意思。

使用Git 2.13(2017年第2季度),git状态的性能应该会提高。

见杰夫Hostetler( jeffhostetler ) 承诺950a234 (2017年4月14日) 。
(由Junio C gitster合并- gitster – 2017年4月24日承诺8b6bba6 )

> string-listALLOC_GROW分配string_list时使用ALLOC_GROWmacros

使用ALLOC_GROW()macros来重新分配一个string_list数组,而不是简单的增加32。
这是一个性能优化。

在一个非常大的repo状态下,有很多更改,总运行时间的很大一部分花费在重新wt_status.changes数组 。

这个更改将wt_status_collect_changes_worktree()的时间从125秒减less到45秒。