git stash在Windows上很慢

在我的Windows机器上,GIT_TRACE_PERFORMANCE=true git stash list每次调用有大约3.5秒的开销,这给我的git commit钩子增加了大约7秒的时间。

在Linux(同一台机器)下,相同的命令大约需要0.01秒。 性能问题也适用于空存储库。

我从这个线程和这个线程尝试了以下内容:

  • GIT_TRACE_PERFORMANCE=true git stash list设置为256
  • GIT_TRACE_PERFORMANCE=true git stash list is set to 256
  • GIT_TRACE_PERFORMANCE=true git stash list is set to 256
  • 设置PS1 ='$'
  • 在管理员模式下运行cmd
  • 在cmd.exe而不是git-bash中运行

运行GIT_TRACE_PERFORMANCE=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

Running 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秒钟。 我还有其他可以发现瓶颈的标志吗?

sighol asked 2020-01-22T19:31:48Z
2个解决方案
21 votes

使用适用于Windows 2.19的Git(2018年9月),check_changes()(和do_create_stash())不再仅是脚本,而是实际上是使用create_stash()编译的二进制文件。
参见git-for-windows / build-extra PR 203。

要激活它们,请键入:

git config --global rebase.useBuiltin true
git config --global stash.useBuiltin true

警告:

尽管提速效果不错,但这些补丁仍在不断变化,而且根本没有经过战斗测试。

因此,到目前为止,脚本版本check_changes()仍为默认脚本,即:

  • 希望我们通过三个并行的Google Summer of Code项目获得的原始速度改进的用户可以拥有,
  • 而其他不愿意只运行经过良好测试的代码来玩豚鼠的人则可以保持安全。

重点仍然是:在Git的下一版本中,用于check_changes()的bash脚本最终将消失,并且其替换速度将会更快。


使用Git 2.22更新2019年第二季度,check_changes()完全用C重写。

请参阅Paul-Sebastian(2019年2月25日)(参见2019年2月25日) check_changes())。
请参阅Joel Teichroeb(check_changes())的提交c4de61d,提交577c199,提交4e2dd39,提交8a0fc8d(2019年2月25日)。
参见Johannes Schindelin(check_changes())的提交7906af0,提交90a4627和提交8d8e9c2(2019年2月25日)。
(由Junio C Hamano合并-check_changes()-在commit e36adf7中,2019年4月22日)

您仍然可以将Shell脚本与check_changes()一起使用。

和:

check_changes():将do_create_stash()转换为create_stash()

旧的外壳脚本check_changes()已删除,并完全替换为do_create_stash()
为此,将create_stash()get_untracked_files()改编为无需stash.sh

例如,在此提交之前,check_changes()称为do_create_stash()。如果调用create_stash(),则   其中一些更改是不必要的。

此提交还删除了check_changes()一词,因为现在隐藏   直接调用而不是由Shell脚本调用。

有一些优化:

check_changes():优化do_create_stash()create_stash()

此提交通过避免调用   同样的功能。
例如,check_changes()在某些时候将调用以下函数:

  • check_changes()(内部do_create_stash()
  • check_changes(),该电话:do_create_stash()和   create_stash()

请注意check_changes()也称为do_create_stash()
因此,create_stash()被称为2次,get_untracked_files()被称为2次   3次。

旧功能check_changes()现在包含两个功能:   do_create_stash()create_stash()

这些是check_changes()do_create_stash()的电话链:

  • check_changes()-> do_create_stash()-> create_stash()
  • check_changes()-> do_create_stash()

为了防止一遍又一遍地调用相同的函数,现在将do_create_stash()中的27142822279150150552放置在调用程序函数中(create_stash()do_push_stash())。
这样就叫check_changes()get_untracked files()   只有一次。

VonC answered 2020-01-22T19:34:44Z
3 votes

-x是脚本,而不是在/usr/lib/git-core/git-stash二进制文件中编译的命令。

在Linux上:我可以在/usr/lib/git-core/git-stash上找到-x-我会让您在Windows上寻找正确的路径...


该脚本使用-x运行,我不知道在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标志,该标志将打印所有执行的命令的痕迹,并目视检查其中一个子命令是否似乎是衣架:

$ PATH=/usr/lib/git-core:$PATH bash -x /usr/lib/git-core/git-stash
LeGEC answered 2020-01-22T19:35:22Z
translate from https://stackoverflow.com:/questions/37529016/git-stash-is-slow-on-windows