与 Libgit2 相比,Windows 上的 Git 存储速度极慢
Posted
技术标签:
【中文标题】与 Libgit2 相比,Windows 上的 Git 存储速度极慢【英文标题】:Git stash on windows extremly slow compared to Libgit2 【发布时间】:2017-10-24 21:14:03 【问题描述】:最近我已经多次使用 git stash 并且我一直认为它真的很慢,即使在具有单个文件的新存储库上也是如此。我已阅读 this question 关于 git stash 缓慢和 this other one 并尝试了这些问题的所有答案,但实际上没有任何效果。
例如,我已完成以下步骤来重现它:
git init
touch file.txt
vim file.txt
(编辑文件添加2行)
git add .
git commit -m "Initial commit"
vim file.txt
(再次编辑添加 1 行)
time git stash
输出:
$ time git stash
Saved working directory and index state WIP on master: b9454ed Initial commit
HEAD is now at b9454ed Initial commit
real 0m8.042s
user 0m0.000s
sys 0m0.046s
8 秒存储单行是这么多时间。 现在使用 libgit2sharp 进行测试:
static void Main(string[] args)
Repository repo=new Repository(@"C:\Users\UserTest\TestGitRepo");
repo.Stashes.Add(new Signature("test", "test@test.com", new DateTimeOffset(DateTime.Now)), "Stash on master");
此代码需要 74 毫秒来存储相同的更改。
如果 Libgit2 这么快,那么应该可以加快 git stash
命令的速度。我怎样才能做到这一点?
实际使用的是 windows 10 64bit 和 git 2.11 64bits。其他 git 命令(如状态、添加、提交等)工作正常。
更新:我已经更新到 git 2.13,现在 git stash
是 14,53s...
更新 2:我已更新到 git 2.15 并尝试相同的测试 time git stash
返回 real 0m6,553s
。还是很慢……
【问题讨论】:
实际上,在我的电脑上创建了一个sh.exe.stackdump
,你能验证git stash
确实做了它应该做的事情吗?
@LasseV.Karlsen 它达到了预期的效果。最后一行在两种情况下都使用我的问题的步骤隐藏。
是的,这条线也藏在我这边,但 bash 也因堆栈溢出而崩溃。但这并没有考虑到所花费的时间,所以请忽略我的 cmets。
啊,由于某种原因,我设法回到 64 位版本的 git,它在 bash 中存在堆栈溢出异常问题。恢复了 32 位,故障转储消失了。
许多 Git 命令被编写为 shell 脚本。在 Linux 和 Unix 系统上,它们在完全合理的时间内运行。在 Windows 上,显然(我不使用 Windows,所以我没有经历过这种情况),它们运行得非常缓慢。因此,Git 人员一直在重写越来越多的 Git 命令,以避免使用 shell 脚本。我想知道修复导致 shell 如此缓慢的任何问题是否更有利可图,但这也许是 Windows 的基础。
【参考方案1】:
自 Git 2.22
从 Git 2.22 开始,之前的实验性功能现已稳定并成为默认选项。
低于 Git 2.22
一年后,安装 Git 2.19 我在 git 安装期间看到了一个复选框,用于启用新的 experimental 内置存储。
在我的情况下,它运行良好,并且我注意到与旧实现(使用脚本)相比巨大的性能改进,它实际上与在 linux 中使用相同的命令一样快。
这里的结果完全相同的步骤:
$ time git stash
Saved working directory and index state WIP on master: 7a29b92 Initial commit
real 0m0,120s
user 0m0,000s
sys 0m0,015s
【讨论】:
【参考方案2】:要添加到现有答案,如果您已经安装了 2.19 或更高版本,则可以启用新功能:
git config --global stash.usebuiltin true
这也适用于便携版。
请注意,此功能似乎还不适用于子模块。 https://github.com/git-for-windows/git/issues/1820
【讨论】:
看起来他们在你回答后不久就关闭了那个错误!【参考方案3】:git stash
使用 Git 2.25(2020 年第一季度)将更快,oneway_merge()
的用户(如“reset --hard”)学会了利用fsmonitor
来避免不必要的lstat
(2) 调用。
(从 Git 2.22 开始,2019 年第二季度,git stash
is entirely rewritten in C,并且是默认值)
参见Utsav Shah (Utsav2
) 的commit 679f2f9(2019 年 11 月 20 日)。(由 Junio C Hamano -- gitster
-- 合并于 commit 473b431,2019 年 12 月 5 日)
unpack-trees
: 跳过 fsmonitor 有效文件的统计信息协助人:Junio C Hamano协助人:Kevin Willford签字人:Utsav Shah
索引可能知道一个文件没有通过
fsmonitor
修改,但 unpack-trees 没有注意到它并通过ie_match_stat
进行检查,这在某些文件系统上可能效率低下。 这会显着减慢运行oneway_merge
的命令,例如checkout
和git reset --hard
。这个补丁让
oneway_merge
通过fsmonitor
检查一个文件是否被认为没有改变,并跳过ie_match_stat
。 unpack-trees 现在也可以正确地从源索引中复制fsmonitor
有效性状态。 最后,为了正确起见,我们强制刷新tweak_fsmonitor
中的fsmonitor
状态。在此更改之后,像
stash
之类的命令(在内部使用git reset --hard
)在 mac 上的 250k 文件存储库上从 8 秒或更多到 ~2 秒 .
【讨论】:
以上是关于与 Libgit2 相比,Windows 上的 Git 存储速度极慢的主要内容,如果未能解决你的问题,请参考以下文章
VisualStudio:libgit2 引发错误。类别 = 结帐
是否可以在 Windows 中将 nvcc 与 gcc/g++ 集成?
libgit2-6311e88: cannot open shared object file: No such file or directory