Git retrasa Emacs a la Muerte – ¿Cómo arreglar esto?

Abrir un file (ya sea escribiendo Ctrl-x f , AKA Find File ) o escribiendo f en ese file en modo Dinetworking ), es dolorosamente lento en los directorys que tienen un subdirectory .git .

Incluso el file más simple (50 líneas con comentarios en su mayoría) podría demorar hasta 8 segundos en abrirse.

El mismo file, en un directory diferente no administrado por Git, se abre en un santiamén, de inmediato.

¿Por qué sucede esto y cómo puedo solucionarlo sin desactivar vc-mode? (ya que una de las razones principales por las que uso Emacs es su Mx ediff-revision )

ACTUALIZACIÓN 1: Gracias a la respuesta de @ sanityinc a continuación, ejecuté Perfil ELP y esto es lo que recibí (para un file muy pequeño, 69 líneas, 59 de las cuales son comentarios sencillos):

 Function Name Call Count Elapsed Time Average Time ------------- ---------- ------------ ------------ vc-call-backend 11 23.023 2.093 vc-find-file-hook 1 8.757 8.757 vc-mode-line 1 7.812 7.812 vc-default-mode-line-string 1 7.345 7.345 vc-state-refresh 1 6.921 6.921 vc-state 1 6.921 6.921 vc-default-state-heuristic 1 6.921 6.921 vc-registenetworking 1 0.945 0.945 vc-backend 1 0.945 0.945 vc-git-registenetworking 1 0.912 0.912 vc-working-revision 1 0.4240000000 0.4240000000 vc-find-root 4 0.0990000000 0.0247500000 vconcat 623 0.0220000000 3.53...e-005 vc-bzr-registenetworking 1 0.016 0.016 vc-check-master-templates 2 0.014 0.007 vc-default-registenetworking 2 0.014 0.007 vc-rcs-registenetworking 1 0.008 0.008 vc-sccs-registenetworking 1 0.006 0.006 vc-svn-registenetworking 1 0.002 0.002 vc-cvs-registenetworking 1 0.001 0.001 vc-sccs-search-project-dir 1 0.0 0.0 vc-kill-buffer-hook 6 0.0 0.0 vc-find-backend-function 11 0.0 0.0 vc-default-find-file-hook 1 0.0 0.0 vc-possible-master 6 0.0 0.0 vc-file-clearprops 1 0.0 0.0 vc-file-setprop 3 0.0 0.0 vc-file-getprop 5 0.0 0.0 vc-make-backend-sym 15 0.0 0.0 

Esta es una gran información, pero yo no soy un experto en Emacs / elisp, así que, ¿cómo puedo ir desde aquí?

ACTUALIZACIÓN 2: Después de poner este problema en un segundo plano por un time, me encontré con esta gran publicación de blog: Cygwin arranque lento: el culpable descubierto! que esencialmente sugiere iniciar la finalización del bash en segundo plano. Lo implementé rápidamente y volví a ejecutar la testing de perfil ELP:

 vc-call-backend 11 14.489 1.317 vc-find-file-hook 1 5.488 5.488 vc-mode-line 1 5.118 5.118 vc-default-mode-line-string 1 4.719 4.719 vc-state-refresh 1 4.282 4.282 vc-state 1 4.282 4.282 vc-default-state-heuristic 1 4.282 4.282 vc-working-revision 1 0.437 0.437 vc-registenetworking 1 0.37 0.37 vc-backend 1 0.37 0.37 vc-git-registenetworking 1 0.34 0.34 vc-find-root 4 0.088 0.022 vc-bzr-registenetworking 1 0.015 0.015 vc-check-master-templates 2 0.013 0.0065 vc-default-registenetworking 2 0.013 0.0065 vc-rcs-registenetworking 1 0.007 0.007 vc-sccs-registenetworking 1 0.006 0.006 vc-cvs-registenetworking 1 0.001 0.001 vconcat 623 0.001 1.60...e-006 vc-svn-registenetworking 1 0.001 0.001 vc-sccs-search-project-dir 1 0.0 0.0 vc-kill-buffer-hook 6 0.0 0.0 vc-find-backend-function 11 0.0 0.0 vc-default-find-file-hook 1 0.0 0.0 vc-possible-master 6 0.0 0.0 vc-file-clearprops 1 0.0 0.0 vc-file-setprop 3 0.0 0.0 vc-file-getprop 5 0.0 0.0 vc-make-backend-sym 15 0.0 0.0 

Es genial ver que vc-call-backend baje de 23 segundos a 14 segundos, pero esto todavía es inaceptable (¡encontrar un file controlado por CVS lleva less de una fracción de segundo!).

ACTUALIZACIÓN 3: Incapaz de resolver el misterio, intenté mi suerte actualizando a la última cygwin (1.7.9-1). Eso no ayudó.

Por lo tanto, decidí intentar mover la caja de arena (junto con su subdirectory .git ) del recurso compartido de Samba al almacenamiento local ( C:\Users\WinWin\Documents ). Luego volví a ejecutar la testing de perfil ELP:

 vc-call-backend 11 2.082 0.1892727272 vc-find-file-hook 1 0.897 0.897 vc-git--call 7 0.8929999999 0.1275714285 vc-git-mode-line-string 1 0.78 0.78 vc-mode-line 1 0.78 0.78 vc-default-mode-line-string 1 0.655 0.655 vc-git--out-ok 5 0.6519999999 0.1304 vc-git-state 1 0.53 0.53 vc-state-refresh 1 0.53 0.53 vc-state 1 0.53 0.53 vc-default-state-heuristic 1 0.53 0.53 vc-git-working-revision 2 0.25 0.125 vc-git-registenetworking 2 0.2239999999 0.1119999999 vc-git--run-command-string 1 0.18 0.18 vc-working-revision 1 0.125 0.125 vc-registenetworking 1 0.1169999999 0.1169999999 vc-backend 2 0.1169999999 0.0584999999 vc-git--empty-db-p 1 0.11 0.11 vc-find-root 3 0.003 0.001 vc-git-root 2 0.002 0.001 vc-check-master-templates 2 0.001 0.0005 vc-sccs-registenetworking 1 0.001 0.001 vc-default-registenetworking 2 0.001 0.0005 vc-bzr-registenetworking 1 0.001 0.001 vc-rcs-registenetworking 1 0.0 0.0 vc-sccs-search-project-dir 1 0.0 0.0 vc-kill-buffer-hook 5 0.0 0.0 vc-default-find-file-hook 1 0.0 0.0 vc-possible-master 6 0.0 0.0 vc-cvs-registenetworking 1 0.0 0.0 vc-file-clearprops 1 0.0 0.0 vc-file-setprop 3 0.0 0.0 vc-file-getprop 5 0.0 0.0 vc-svn-registenetworking 1 0.0 0.0 vc-make-backend-sym 2 0.0 0.0 

¡Guauu! Eso bajó vc-call-backend de 14 segundos a 2 segundos. Esto es genial, pero no maravilloso, porque con Emacs / CVS puedo visitar un file en less de 35 ms , en el mismo recurso compartido de Samba donde reside originalmente el entorno limitado:

 vc-call-backend 5 0.031 0.0062 vc-find-file-hook 1 0.031 0.031 vc-registenetworking 1 0.031 0.031 vc-backend 1 0.031 0.031 vc-rcs-registenetworking 1 0.016 0.016 vc-check-master-templates 1 0.016 0.016 vc-default-registenetworking 1 0.016 0.016 vc-insert-file 1 0.015 0.015 vc-cvs-get-entries 1 0.015 0.015 vc-cvs-registenetworking 1 0.015 0.015 vc-cvs-state-heuristic 1 0.0 0.0 vc-cvs-parse-sticky-tag 1 0.0 0.0 vc-kill-buffer-hook 1 0.0 0.0 vc-find-backend-function 1 0.0 0.0 vc-cvs-parse-entry 1 0.0 0.0 vc-mode-line 1 0.0 0.0 vc-default-find-file-hook 1 0.0 0.0 vc-possible-master 3 0.0 0.0 vc-cvs-mode-line-string 1 0.0 0.0 vc-default-mode-line-string 1 0.0 0.0 vc-state-refresh 1 0.0 0.0 vc-working-revision 1 0.0 0.0 vc-state 1 0.0 0.0 vc-file-clearprops 1 0.0 0.0 vc-file-setprop 5 0.0 0.0 vc-file-getprop 7 0.0 0.0 vc-make-backend-sym 2 0.0 0.0 

Esto plantea 2 preguntas:

  1. ¿Qué en la combinación de git + cygwin lo hace tan sensible a la velocidad de la networking?
  2. ¿Cómo puedo hacer que Git baje a less de 50 ms? Después de todo, se llama "el sistema de control de versiones rápidas "

Actualizar cuando se usa msysgit 1.7.8:

 vc-call-backend 11 0.626 0.0569090909 vc-find-file-hook 1 0.281 0.281 vc-mode-line 1 0.2189999999 0.2189999999 vc-default-mode-line-string 1 0.1879999999 0.1879999999 vc-state-refresh 1 0.157 0.157 vc-state 1 0.157 0.157 vc-default-state-heuristic 1 0.157 0.157 vc-registenetworking 1 0.062 0.062 vc-backend 1 0.062 0.062 vc-git-registenetworking 1 0.062 0.062 vc-working-revision 1 0.0310000000 0.0310000000 vc-rcs-registenetworking 1 0.0 0.0 vc-sccs-search-project-dir 1 0.0 0.0 vc-kill-buffer-hook 6 0.0 0.0 vc-find-backend-function 11 0.0 0.0 vc-default-find-file-hook 1 0.0 0.0 vc-possible-master 6 0.0 0.0 vc-check-master-templates 2 0.0 0.0 vc-cvs-registenetworking 1 0.0 0.0 vc-sccs-registenetworking 1 0.0 0.0 vc-file-clearprops 1 0.0 0.0 vconcat 623 0.0 0.0 vc-default-registenetworking 2 0.0 0.0 vc-file-setprop 3 0.0 0.0 vc-find-root 4 0.0 0.0 vc-file-getprop 5 0.0 0.0 vc-bzr-registenetworking 1 0.0 0.0 vc-svn-registenetworking 1 0.0 0.0 vc-make-backend-sym 15 0.0 0.0 

¿Puede usted decir la diferencia? 🙂

Git bajo Emacs es mucho más rápido ahora, pero aún mucho más lento que CVS bajo Emacs. Así que no tengo idea de por qué se llama a Git el "Sistema de control de versiones rápidas". Puede ser mejor que CVS, ¿pero más rápido?

Hay un generador de perfiles integrado llamado ELP. Puedes probar algo como Mx elp-instrument-package , ingresar "vc" y luego intentar encontrar un file. Luego, Mx elp-results le mostrará un informe de perfil.

(Tenga en count que si el time se gasta en funciones no relacionadas con vc, esta técnica no lo mostrará, pero puede instrumentar otros packages si lo desea).

Puede tratar de crear un perfil de la apertura de su file para ver exactamente lo que toma tanto time.

Puede deshabilitar vc-mode configurando vc-handled-backends .emacs vc-handled-backends en nil en sus .emacs .

Tuve el mismo problema con el uso de Windows Git 2.10 de mingw emacs 25.1.1.

Usando lo siguiente para probar:

 (progn ;; make sure the buffer is not already open (elp-instrument-function 'find-file-other-window) (elp-instrument-function 'vc-git-registenetworking) (elp-instrument-function 'vc-git-mode-line-string) (elp-instrument-function 'vc-git-find-file-hook) (find-file-other-window "my-file-in-a-git-repo") (elp-results) (elp-restre-all)) 

Dio el siguiente perfil:

 find-file-other-window 1 1.1076142 1.1076142 vc-git-mode-line-string 1 0.6396082 0.6396082 vc-git-find-file-hook 1 0.2652034 0.2652034 vc-git-registenetworking 1 0.1872024 0.1872024 

La function vc-git-mode-line-string toma un time. Esto muestra algo así como Git:mybranch en la línea de modo de tu window. No me importa lo suficiente como para esperarlo siempre, así que sobrescribo la implementación para simplemente devolver "Git" :

 (defun vc-git-mode-line-string (file) "Overwritten default vc-git-el implementation. Return a string for `vc-mode-line' to put in the mode line for FILE." "Git") 

La function vc-git-find-file-hook abrirá un modo de edición de conflicto bastante bueno si está abriendo un file en conflicto. La implementación primero llamaba a vc-git-conflicted-files que demora un time, y luego realiza una comprobación bastante trivial de si las líneas comienzan con <<<<<<< . Simplemente cambié los dos, y ahora la implementación demora aproximadamente 0.0 segundos en la mayoría de los casos.

 (defun vc-git-find-file-hook () "Overwritten default vc-git-el implementation. Activate `smerge-mode' if there is a conflict." (when (and buffer-file-name ;; FIRST check whether this file looks like a conflicted file (save-excursion (goto-char (point-min)) (re-search-forward "^<<<<<<< " nil 'noerror)) ;; THEN ask git if it really is a conflict (vc-git-conflicted-files buffer-file-name)) (vc-file-setprop buffer-file-name 'vc-state 'conflict) (smerge-start-session) (when vc-git-resolve-conflicts (add-hook 'after-save-hook 'vc-git-resolve-when-done nil 'local)) (vc-message-unresolved-conflicts buffer-file-name))) 

Resultados:

 find-file-other-window 1 0.2838039 0.2838039 vc-git-registenetworking 1 0.2682037 0.2682037 vc-git-find-file-hook 1 0.0 0.0 vc-git-mode-line-string 1 0.0 0.0