繁体   English   中英

git stash 在 Windows 上运行缓慢

[英]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
  • 设置 PS1='$'
  • 在管理模式下运行 cmd
  • cmd.exe而不是 git-bash 中运行

运行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 36​​9ae75 ,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 40af146commit 48ee24acommit ef0f0b4commit 64fe9c2commit 1ac528ccommit d553f53,8 commit d , 05dc commit3,8commit05dccommit d37commit d37 , commit dac566c , commit ab8ad46 (25 Feb 2019) by Paul-Sebastian Ungureanu ( weekly-digest[bot] )
请参阅Joel Teichroeb ( klusark ) 的commit c4de61dcommit 577c199commit 4e2dd39commit 8a0fc8d (2019 年 2 月 25 日
请参阅Johannes Schindelin ( dscho ) 的commit 7906af0commit 90a4627commit 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
为了做到这一点, createpush适合在没有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()

这些是pushcreate的调用链:

  • 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM