git stash在windows上很慢

时间:2016-05-30 15:16:04

标签: windows git git-bash git-stash

在我的Windows机器上git stash每次调用都有大约3.5秒的开销,这为我的git commit hook添加了大约7秒。

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

我在this threadthis thread尝试了以下内容:

  • 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秒钟。我可以运行其他任何标志来找到瓶颈吗?

2 个答案:

答案 0 :(得分:21)

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.22更新了Q2 2019,git stash完全用C重写。

请参见commit 40af146commit 48ee24acommit ef0f0b4commit 64fe9c2commit 1ac528ccommit d553f53commit d4788af,{{3} },commit 41e0dd5commit dc7bd38commit 130f269commit bef55dccommit dac566c(2019年2月25日)由commit ab8ad46撰写。
请参见Paul-Sebastian Ungureanu (weekly-digest[bot])commit c4de61dcommit 577c199commit 4e2dd39commit 8a0fc8d(2019年2月25日)。
请参见Joel Teichroeb (klusark)commit 7906af0commit 90a4627commit 8d8e9c2(2019年2月25日)。
(由Johannes Schindelin (dscho)Junio C Hamano -- gitster --中合并,2019年4月22日)

您仍然可以commit e36adf7

并且:

  

use the shell script with git legacy-stash

     

旧的外壳程序脚本git-stash.sh已删除,并完全由builtin/stash.c取代。
  为了做到这一点,createpush可以在没有stash.sh的情况下工作。

     

例如,在此提交之前,git stash create被称为git stash--helper create --message "$*"。如果它叫git stash--helper create "$@",则   其中某些更改是不必要的。

     

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

有一些优化:

  

stash: convert stash--helper.c into stash.c

     

此提交通过避免调用   同样的功能。
  例如,git stash push -u会在某些时候调用以下函数:

     
      
  • check_changes()(在do_push_stash()内部)
  •   
  • do_create_stash(),它调用:check_changes()和   get_untracked_files()
  •   
     

请注意,check_changes()也会调用get_untracked_files()
  因此,check_changes()被调用了两次,而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()内的do_create_stash()放在调用者函数(create_stash()do_push_stash())中。
  这样check_changes()get_untracked files()被称为   只有一次。

答案 1 :(得分:3)

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标志,该标志将打印所有已执行命令的跟踪,并直观地检查其中一个子命令是否为挂钩:

$ PATH=/usr/lib/git-core:$PATH bash -x /usr/lib/git-core/git-stash