web-dev-qa-db-fra.com

git stash est lent sur windows

Sur ma machine Windows git stash a environ 3,5 secondes de surcharge à chaque appel, ce qui ajoute environ 7 secondes à mon hook de validation git.

La même commande sous Linux (même machine) prend environ 0,01 seconde. Le problème de performances s'applique également aux référentiels vides.

J'ai essayé ce qui suit de ce fil et ce fil :

  • core.fscache est défini sur true
  • core.preloadindex est défini sur true
  • gc.auto est réglé sur 256
  • Réglage PS1 = '$'
  • Exécution de cmd en mode d'administration
  • Exécution à l'intérieur cmd.exe au lieu de git-bash

Fonctionnement 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

Fonctionnement 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                                                                                                                                                                                          

D'après le journal, nous voyons qu'il faut environ 3 secondes entre l'exécution de la commande git-stash et l'exécution de git-rev-parse. Y a-t-il d'autres indicateurs que je peux exécuter pour trouver le goulot d'étranglement?

50
sighol

Avec Git pour Windows 2.19 (septembre 2018), git stash (Et git rebase) Ne sont plus uniquement script, mais en fait un binaire compilé avec git.exe.
Voir git-for-windows/build-extra PR 2 .

Pour les activer, saisissez:

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

Avertissement :

Aussi agréables que soient les accélérations, les patchs en question sont toujours en évolution, et ils ne sont pas du tout testés au combat.

Donc, pour l'instant, la version de script de git stash Reste la valeur par défaut de cette façon:

  • les utilisateurs qui souhaitent améliorer la vitesse brute que nous avons obtenue grâce à trois projets Google Summer of Code fonctionnant en parallèle peuvent le faire,
  • tandis que d'autres qui hésitent à jouer au cobaye en exécutant uniquement du code bien testé peuvent rester prudents.

Le point demeure: dans les prochaines versions de Git, le script bash pour git-stash Finira par disparaître, et son remplacement est et sera plus rapide.


Mise à jour Q2 2019, avec Git 2.22, git stash Est entièrement réécrit en C.

Voir commit 40af146 , commit 48ee24a , commit ef0f0b4 , commit 64fe9c2 , commit 1ac528c , commit d553f5 , commit d4788af , commit 41e0dd5 , commit dc7bd38 , commit 130f269 , commit bef55dc , commit dac566c , commit ab8ad46 (25 février 2019) par Paul-Sebastian Ungureanu (weekly-digest[bot]) .
Voir commit c4de61d , commit 577c199 , commit 4e2dd39 , commit 8a0fc8d (25 février 2019) par Joel Teichroeb (klusark) .
Voir commit 7906af , commit 90a4627 , commit 8d8e9c2 (25 février 2019) par Johannes Schindelin (dscho) .
(Fusionné par Junio ​​C Hamano - gitster - in commit e36adf7 , 22 avril 2019)

Vous pouvez toujours tiliser le script Shell avec git legacy-stash .

Et:

stash: convertir stash--helper.c en stash.c

L'ancien script Shell git-stash.sh A été supprimé et remplacé entièrement par builtin/stash.c.
Pour ce faire, create et Push ont été adaptés pour fonctionner sans stash.sh.

Par exemple, avant cette validation, git stash create A appelé git stash--helper create --message "$*". S'il appelait git stash--helper create "$@", Certaines de ces modifications n'auraient pas été nécessaires.

Cette validation supprime également le mot helper puisque maintenant stash est appelé directement et non par un script Shell.

Il y a des optimisations:

stash: optimisez get_untracked_files() et check_changes()

Cette validation introduit une optimisation en évitant d'appeler à nouveau les mêmes fonctions.
Par exemple, git stash Push -u Appelle à certains moments les fonctions suivantes:

  • check_changes() (à l'intérieur do_Push_stash())
  • do_create_stash(), qui appelle: check_changes() et get_untracked_files()

Notez que check_changes() appelle également get_untracked_files().
Ainsi, check_changes() est appelée 2 fois et get_untracked_files() 3 fois.

L'ancienne fonction check_changes() se compose désormais de deux fonctions: get_untracked_files() et check_changes_tracked_files().

Ce sont les chaînes d'appel pour Push et create:

  • Push_stash() -> do_Push_stash() -> do_create_stash()
  • create_stash() -> do_create_stash()

Pour éviter d'appeler les mêmes fonctions encore et encore, check_changes() à l'intérieur de do_create_stash() est maintenant placé dans les fonctions de l'appelant (create_stash() et do_Push_stash()) .
De cette façon, check_changes() et get_untracked files() ne sont appelés qu'une seule fois.

21
VonC

git-stash est un script, pas une commande compilée dans le git.exe binaire.

Sur linux: je peux trouver git-stash à /usr/lib/git-core/git-stash - Je vous laisse chercher le chemin correct sous windows ...


Ce script utilise #!/bin/sh pour fonctionner, je ne sais pas quelle implémentation Shell est utilisée lorsque vous exécutez cela sur Windows.

Vous pouvez essayer de l'exécuter avec un autre Shell compatible (ici: 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

Vous pouvez également activer le -x flag, qui affichera une trace de toutes les commandes exécutées et vérifiera visuellement si l'une des sous-commandes semble être le crochet:

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