git status 的性能应该会在 Git 2.13(2017 年第 2 季度)中得到改善。
参见Jeff Hostetler (jeffhostetler) 的commit 950a234(2017 年 4 月 14 日)。
(由 Junio C Hamano -- gitster -- 合并于 commit 8b6bba6,2017 年 4 月 24 日)
> string-list: 重新分配 string_list 时使用 ALLOC_GROW macro
在重新分配string_list 数组时使用ALLOC_GROW() 宏
而不是简单地增加 32。
这是性能优化。
在一个非常大的回购状态期间,有很多变化,
总运行时间的很大一部分用于重新分配wt_status.changes array。
此更改将我非常大的存储库中 wt_status_collect_changes_worktree() 中的时间从 125 秒减少到 45 秒。
此外,Git 2.17(2018 年第 2 季度)将引入新的跟踪,用于衡量在索引繁重的操作中花费的时间。
参见commit ca54d9bcommit ca54d9b(2018 年 1 月 27 日)。
(由 Junio C Hamano -- gitster -- 合并于 commit 090dbea,2018 年 2 月 15 日)
trace:衡量索引繁重的操作花费的时间
测量所有已知的重代码块(对象数据库除外
使用权)。这应该有助于确定优化是否有效或
不是。
未优化的 git-status 会给出如下内容:
0.001791141 s: read cache ...
0.004011363 s: preload index
0.000516161 s: refresh index
0.003139257 s: git command: ... 'status' '--porcelain=2'
0.006788129 s: diff-files
0.002090267 s: diff-index
0.001885735 s: initialize name hash
0.032013138 s: read directory
0.051781209 s: git command: './git' 'status'
相同的 Git 2.17(2018 年第二季度)改进了 git status:
revision.c: 减少对象数据库查询
在mark_parents_uninteresting() 中,我们检查是否存在
目标文件,看看我们是否应该将提交视为已解析。结果
是在提交上设置“已解析”位。
修改条件只检查has_object_file()如果结果
会改变解析的位。
当本地分支与其上游引用不同时,“git status”
将计算提前/落后计数。
这使用paint_down_to_common() 并点击mark_parents_uninteresting()。
在远程分支“origin/master”后面的本地实例“master”的 Linux 存储库副本上,大约 60,000 次提交,我们发现
“git status”从 1.42 秒变为 1.32 秒,对于一个亲戚
差异为 -7.0%。
Git 2.24(2019 年第三季度)提出了另一种设置来提高 git status 的性能:
参见commit aaf633c、commit c6cc4c5、commit ad0fb65、commit 31b1de6、commit b068d9a、commit 7211b9e(2019 年 8 月 13 日)Derrick Stolee (derrickstolee)。
(由Junio C Hamano -- gitster -- 合并commit f4f8dfe,2019 年 9 月 9 日)
repo-settings:创建 feature.manyFiles 设置
feature.manyFiles 设置适用于具有许多
工作目录中的文件。
通过设置index.version=4 和core.untrackedCache=true,'git status' 等命令应该会得到改进。
但是:
在 Git 2.24(2019 年第四季度)中,读取 index.version 配置的代码路径因最近的更新而被破坏,该更新已得到纠正。
参见Derrick Stolee (derrickstolee)commit c11e996(2019 年 10 月 23 日)。
(由 Junio C Hamano -- gitster -- 合并到 commit 4d6fb2b,2019 年 10 月 24 日)
签字人:Derrick Stolee
多个配置选项被合并到 ds/feature-macros 中的 repo_settings 结构中,包括移动 7211b9e 中的“index.version”配置设置(“repo-settings:整合一些配置设置”,2019 -08-13,Git v2.24.0-rc1 -- merge 在batch #0 中列出)。
不幸的是,该文件看起来像很多样板文件,显然是复制粘贴过载的一个因素,配置设置被解析为 repo_config_ge_bool() 而不是 repo_config_get_int()。这意味着设置“index.version=4”将无法正确注册,并将恢复为默认版本 3。
我在将 v2.24.0-rc0 合并到 Git 代码库的 VFS 时发现了这一点,我们非常关心索引是在版本 4 中。
这没有被代码库捕获,因为放在t1600-index.sh 中的版本检查没有足够测试“基本”场景。在这里,我们修改测试以包含这些正常设置,以免被features.manyFiles 或GIT_INDEX_VERSION 覆盖。
虽然“默认”版本是 3,但在不需要时会在 do_write_index() 中降级为版本 2。
由于 Git 2.33(2021 年第三季度),git status 也将更快地比较 SHA1,在写入索引文件的代码路径中使用优化的哈希文件 API。
参见Derrick Stolee (derrickstolee)commit f6e2cd0、commit 410334e、commit 2ca245f(2021 年 5 月 18 日)和 commit 68142e1(2021 年 5 月 17 日)。
(由@987654364 中的Junio C Hamano -- gitster -- 合并@,2021 年 6 月 14 日)
签字人:Derrick Stolee
hashfile API 使用 8KB 的硬编码缓冲区大小,并且自从它在 c38138c 中引入以来一直存在(“git-pack-objects: write the pack files with a SHA1 csum”, 2005-06-26, Git v0 .99 -- merge)。
它执行与 read-cache.c 中的哈希缓冲区类似的功能,但该代码在 f279894 中从 8KB 更新为 128KB(“read-cache:使索引写入缓冲区大小为 128K”,2021-02-18,Git v2 .31.0-rc1 -- merge)。
理由是 do_write_index() 从 1.02 秒提高到 0.72 秒。
由于我们的最终目标是让索引编写代码使用 hashfile API,我们需要统一这个缓冲区大小以避免性能下降。
由于这些缓冲区现在位于堆上,我们可以根据消费者的需要调整它们的大小。
特别是,hashfd_throughput() 的调用者希望在缓冲区刷新时报告进度指示器。
这些调用者更喜欢较小的 8k 缓冲区以避免更新之间的大延迟,尤其是对于网络较慢的用户。
当不使用进度指示器时,最好使用较大的缓冲区。
通过在块格式 API 中添加一个新的 trace2 区域,我们可以看到 'git multi-pack-index write'(man) 的写入部分从 ~1.49s 降低到 ~在 Linux 机器上为 1.47 秒。
这些影响在其他文件系统上可能更加明显或减弱。