[英]git stash is slow on windows
在我的 Windows 机器上,每次调用git stash
大约有 3.5 秒的开销,这为我的 git commit 钩子增加了大约 7 秒。
linux(同一台机器)下同样的命令大约需要0.01秒。 性能问题也适用于空存储库。
core.fscache
设置为true
core.preloadindex
设置为true
gc.auto
设置为256
运行GIT_TRACE=true git stash list
16:58:16.844591 git.c:563 trace: exec: 'git-stash' 'list'
16:58:16.844591 run-command.c:336 trace: run_command: 'git-stash' 'list'
16:58:19.699591 git.c:350 trace: built-in: git 'rev-parse' '--git-dir'
16:58:19.859591 git.c:350 trace: built-in: git 'rev-parse' '--git-path' 'objects'
16:58:20.069591 git.c:350 trace: built-in: git 'rev-parse' '--show-toplevel'
16:58:20.154591 git.c:350 trace: built-in: git 'rev-parse' '--git-path' 'index'
16:58:20.244591 git.c:350 trace: built-in: git 'config' '--get-colorbool' 'color.interactive'
16:58:20.334591 git.c:350 trace: built-in: git 'config' '--get-color' 'color.interactive.help' 'red bold'
16:58:20.424591 git.c:350 trace: built-in: git 'config' '--get-color' '' 'reset'
16:58:20.514591 git.c:350 trace: built-in: git 'rev-parse' '--verify' '--quiet' 'refs/stash'
real 0m3.845s
user 0m0.000s
sys 0m0.047s
运行GIT_TRACE_PERFORMANCE=true git stash list
16:59:18.414591 trace.c:420 performance: 0.001078046 s: git command: 'C:\Program Files\Git\mingw64\libexec\git-core\git.exe' 'rev-parse' '--git-dir'
16:59:18.569591 trace.c:420 performance: 0.000947184 s: git command: 'C:\Program Files\Git\mingw64\libexec\git-core\git.exe' 'rev-parse' '--git-path' 'objects'
16:59:18.779591 trace.c:420 performance: 0.001253627 s: git command: 'C:\Program Files\Git\mingw64\libexec\git-core\git.exe' 'rev-parse' '--show-toplevel'
16:59:18.869591 trace.c:420 performance: 0.001285517 s: git command: 'C:\Program Files\Git\mingw64\libexec\git-core\git.exe' 'rev-parse' '--git-path' 'index'
16:59:18.955591 trace.c:420 performance: 0.001139994 s: git command: 'C:\Program Files\Git\mingw64\libexec\git-core\git.exe' 'config' '--get-colorbool' 'color.interactive'
16:59:19.040591 trace.c:420 performance: 0.001182881 s: git command: 'C:\Program Files\Git\mingw64\libexec\git-core\git.exe' 'config' '--get-color' 'color.interactive.help' 'red bold'
16:59:19.125591 trace.c:420 performance: 0.001128997 s: git command: 'C:\Program Files\Git\mingw64\libexec\git-core\git.exe' 'config' '--get-color' '' 'reset'
16:59:19.215591 trace.c:420 performance: 0.001567766 s: git command: 'C:\Program Files\Git\mingw64\libexec\git-core\git.exe' 'rev-parse' '--verify' '--quiet' 'refs/stash'
16:59:19.295591 trace.c:420 performance: 3.730583540 s: git command: 'C:\Program Files\Git\mingw64\bin\git.exe' 'stash' 'list'
real 0m3.819s
user 0m0.000s
sys 0m0.062s
从日志中我们可以看到,在运行 git-stash 命令和运行 git-rev-parse 之间大约需要 3 秒。 我可以运行任何其他标志来找到瓶颈吗?
使用Git for Windows 2.19 (2018 年 9 月), git stash
(和git rebase
)不再是纯脚本,而是实际上是用git.exe
编译的二进制文件。
请参阅git-for-windows/build-extra PR 203 。
要激活它们,请键入 :
git config --global rebase.useBuiltin true
git config --global stash.useBuiltin true
警告:
与加速一样好,有问题的补丁仍然在不断变化,它们根本没有经过实战测试。
所以,现在, git stash
的脚本版本仍然是默认的,这样:
- 希望我们通过三个并行工作的 Google Summer of Code 项目获得原始速度改进的用户可以拥有,
- 而其他不愿意通过仅运行经过良好测试的代码来玩小白鼠的人可以保持安全。
重点仍然是:在 Git 的下一个版本中, git-stash
的 bash 脚本最终将消失,并且它的替代品将会更快。
注意:下一个版本将是 Git 2.27(2020 年第 2 季度):“ git stash
”保留了一个逃生舱,以便在一些版本中使用脚本版本,但这些版本已经过时了。
它已被移除。
请参阅Thomas Gummerer ( tgummerer
) 提交 8a2cd3f和提交 b0c7362 (2020 年 3 月 3 日) 。
(由Junio C gitster
合并-- gitster
-- in commit 369ae75 ,2020 年 3 月 27 日)
stash
:删除stash.useBuiltin
设置签字人:Thomas Gummerer
删除
stash.useBuiltin
设置,该设置作为逃逸舱口添加以禁用首次随 Git 2.22 发布的内置版本的 stash。携带旧版本是一种维护负担,事实上,自 2.23 版本以来,测试失败已经过时,直到现在没有人注意到。
因此,用户会得到提示,可以退回到该工具的潜在错误版本。
我们过去常常使用
git config
来获取useBuiltin
配置,以避免在生成 legacy-stash 之前更改任何全局状态。
然而,这不再是必要的,所以只需使用 'git_config
' 函数来获取设置。类似于我们在d03ebd411c中所做的(“
rebase
: remove the rebase.useBuiltin setting”, 2019-03-18, Git v2.22.0-rc0 -- merge列在第 5 批中),我们删除了相应的设置rebase,我们保留文档,以便人们在网上搜索时可以参考它,因此我们可以在提交消息中参考它。
2019 年第 2 季度更新,使用 Git 2.22, git stash
完全用 C 重写。 ² 参见commit 40af146 , commit 48ee24a , commit ef0f0b4 , commit 64fe9c2 , commit 1ac528c , commit d553f53,8 commit d , 05dc commit3,8commit , 05dc , commit d37 , commit d37 , commit dac566c , commit ab8ad46 (25 Feb 2019) by Paul-Sebastian Ungureanu ( weekly-digest[bot]
) 。
请参阅Joel Teichroeb ( klusark
) 的commit c4de61d 、 commit 577c199 、 commit 4e2dd39 、 commit 8a0fc8d (2019 年 2 月 25 日) 。
请参阅Johannes Schindelin ( dscho
) 的commit 7906af0 、 commit 90a4627 、 commit 8d8e9c2 (2019 年 2 月 25 日) 。
(由Junio C gitster
合并-- gitster
-- in commit e36adf7,2019年 4 月 22 日)
您仍然可以将 shell 脚本与git legacy-stash
。
并且:
stash
: 将stash--helper.c
转换为stash.c
旧的 shell 脚本
git-stash.sh
被删除并完全替换为builtin/stash.c
。
为了做到这一点,create
和push
适合在没有stash.sh
情况下stash.sh
。例如,在此提交之前,
git stash create
调用git stash--helper create --message "$*"
。 如果它调用git stash--helper create "$@"
,那么其中一些更改就没有必要了。此提交还删除了
helper
一词,因为现在 stash 是直接调用的,而不是由 shell 脚本调用的。
有优化:
stash
:优化get_untracked_files()
和check_changes()
此提交通过避免再次调用相同的函数来引入优化。
例如,git stash push -u
会在某些时候调用以下函数:
check_changes()
(在do_push_stash()
)do_create_stash()
,它调用:check_changes()
和get_untracked_files()
请注意,
check_changes()
也调用get_untracked_files()
。
所以,check_changes()
被调用2次,get_untracked_files()
的3倍。旧函数
check_changes()
现在由两个函数组成:get_untracked_files()
和check_changes_tracked_files()
。这些是
push
和create
的调用链:
push_stash()
->do_push_stash()
->do_create_stash()
create_stash()
->do_create_stash()
为了防止一遍
check_changes()
调用相同的函数,check_changes()
do_create_stash()
现在被放置在调用者函数中(create_stash()
和do_push_stash()
)。
这样check_changes()
和get_untracked files()
只被调用一次。
git-stash
是一个脚本,而不是在git.exe
二进制文件中编译的命令。
在Linux上:我能找到git-stash
在/usr/lib/git-core/git-stash
-我会让你看起来对于Windows上的正确的路径...
这个脚本使用#!/bin/sh
来运行,我不知道你在windows上运行的时候用的是什么shell实现。
您可以尝试使用另一个兼容的 shell 运行它(此处:bash):
# the git-core/ dir needs to be in the PATH,
# obviously you will need to provide the correct path for your git-core dir
$ PATH=/usr/lib/git-core:$PATH bash /usr/lib/git-core/git-stash
您还可以打开-x
标志,该标志将打印所有已执行命令的跟踪,并直观地检查其中一个子命令是否似乎是 hanger :
$ PATH=/usr/lib/git-core:$PATH bash -x /usr/lib/git-core/git-stash
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.