performance - tag - ¿qué hace git log-oneline?
Formas de mejorar el rendimiento del estado de git (7)
El rendimiento del estado de git debería mejorar con Git 2.13 (Q2 2017).
Ver commit 950a234 (14 abr 2017) por Jeff Hostetler ( jeffhostetler
) .
(Fusionado por Junio C Hamano - gitster
- in commit 8b6bba6 , 24 de abril de 2017)
> string-list
: use la macro ALLOC_GROW al reallociar string_list
Utilice la macro
ALLOC_GROW()
al reallociar una matrizstring_list
lugar de simplemente aumentarla en 32.
Esta es una optimización del rendimiento.Durante el estado en un repositorio muy grande y hay muchos cambios, un porcentaje significativo del tiempo total de ejecución se gasta en reasignar la matriz
wt_status.changes
.Este cambio disminuye el tiempo en
wt_status_collect_changes_worktree()
de 125 segundos a 45 segundos en mi gran repositorio.
Además, Git 2.17 (Q2 2018) introducirá un nuevo rastro, para medir dónde se gasta el tiempo en las operaciones de índice pesado.
Ver commit ca54d9b (27 de enero de 2018) por Nguyễn Thái Ngọc Duy ( pclouds
) .
(Fusionado por Junio C Hamano - gitster
- en commit 090dbea , 15 Feb 2018)
trace
: mida dónde se gasta el tiempo en las operaciones de índice pesadoSe miden todos los bloques de código pesados conocidos (excepto el acceso a la base de datos de objetos). Esto debería ayudar a identificar si una optimización es efectiva o no.
Un estado de git no optimizado daría algo como lo siguiente:
0.001791141 s: read cache ...
0.004011363 s: preload index
0.000516161 s: refresh index
0.003139257 s: git command: ... ''status'' ''--porcelain=2''
0.006788129 s: diff-files
0.002090267 s: diff-index
0.001885735 s: initialize name hash
0.032013138 s: read directory
0.051781209 s: git command: ''./git'' ''status''
El mismo Git 2.17 (Q2 2018) mejora el git status
con:
commit f39a757 , commit 3ca1897 , commit fd9b544 , commit d7d1b49 (09 de enero de 2018) por Jeff Hostetler (
jeffhostetler
) .
(Fusionada por Junio C Hamano -gitster
- en commit 4094e47 , 08 Mar 2018)
El "git status
" puede pasar muchos ciclos para calcular la relación entre la rama actual y su ascendente, que ahora se puede desactivar con la--no-ahead-behind
"--no-ahead-behind
".commit ebbed3b (25 de febrero de 2018) por Derrick Stolee (
derrickstolee
) .
revision.c
: reducir las consultas de la base de datos de objetosEn
mark_parents_uninteresting()
, verificamos la existencia de un archivo objeto para ver si debemos tratar una confirmación como analizada. El resultado es establecer el bit "analizado" en la confirmación.Modifique la condición para verificar solo
has_object_file()
si el resultado cambiaría el bit analizado.Cuando una sucursal local es diferente de su ref ascendente, el "
git status
" calculará los recuentos por delante / detrás.
Esto usapaint_down_to_common()
y aciertamark_parents_uninteresting()
.En una copia del repositorio de Linux con una instancia local de "maestro" detrás de la rama remota "
origin/master
" por ~ 60,000 confirmaciones, encontramos que el rendimiento del "git status
" pasó de 1.42 segundos a 1.32 segundos, por una diferencia relativa de -7.0%.
Tengo un repositorio de 10 GB en una máquina Linux que está en NFS. La primera vez que el git status
toma 36 minutos y el git status
posterior toma 8 minutos. Parece que Git depende del sistema operativo para almacenar en caché los archivos. Solo los primeros comandos de git
como commit
, status
que involucra pack / reempaquetar todo el repositorio toma mucho tiempo para un gran repositorio. No estoy seguro de si ha usado el git status
en un repositorio tan grande, pero ¿alguien ha encontrado este problema?
He intentado git gc
, git clean
, git repack
pero el tiempo tomado sigue siendo / casi el mismo.
¿Ayudarán los submódulos o cualquier otro concepto, como dividir el repositorio en otros más pequeños? Si es así, cuál es el mejor para dividir un repositorio más grande. ¿Hay alguna otra forma de mejorar el tiempo empleado para los comandos de git en un repositorio grande?
No sé qué sentido tiene, pero para mí el estado fue de 30 minutos, intenté todo lo que pude encontrar en la web, finalmente, lo git reset
. Tenía cientos de cambios que apliqué desde el escondite donde se creó el escondite. una rama diferente pero aplicada en esta rama, todas fueron organizadas pero no confirmadas (simplemente explicando lo que hice diferente antes de toparse con este problema), el git reset
tomó 15 minutos pero después todo comenzó a funcionar rápidamente como menos de un segundo para el estado . No soy un experto en git solo para decir qué resolvió mi problema, espero que ayude a otros que aterricen en esta página.
Para ser más precisos, git depende de la eficiencia de la llamada al sistema lstat(2)
, por lo que ajustar el "tiempo de espera del caché de atributos" de su cliente podría ser el truco.
El manual de git-update-index
, esencialmente un modo manual para git-status
, describe lo que puede hacer para aliviar esto, utilizando el --assume-unchanged
para suprimir su comportamiento normal y actualizar manualmente las rutas que ha cambiado. . Incluso puede programar su editor para desarmar este indicador cada vez que guarde un archivo.
La alternativa, como sugiere, es reducir el tamaño de su pago (el tamaño de los paquetes no entra realmente en juego aquí). Las opciones son un checkout disperso, submódulos o la herramienta repo de Google.
(Hay un hilo de la lista de correo sobre el uso de Git con NFS , pero no responde muchas preguntas).
Prueba git gc . Además, git clean puede ayudar.
ACTUALIZACIÓN : no estoy seguro de dónde proviene el voto negativo, pero el manual de git establece específicamente:
Ejecuta una serie de tareas de limpieza dentro del repositorio actual, como comprimir revisiones de archivos (para reducir el espacio en disco e incrementar el rendimiento ) y eliminar objetos inalcanzables que pueden haberse creado a partir de invocaciones anteriores de git add.
Se recomienda a los usuarios ejecutar esta tarea de forma regular dentro de cada repositorio para mantener una buena utilización del espacio en disco y un buen rendimiento operativo.
¡Siempre noto una diferencia después de ejecutar git gc cuando el estado de git es lento!
ACTUALIZACIÓN II - No estoy seguro de cómo me perdí esto, pero el OP ya probó git gc y git clean. Juro que originalmente no estaba allí, pero no veo ningún cambio en las ediciones. ¡Lo siento por eso!
Si su git repo hace un uso intensivo de los submódulos, puede acelerar mucho el rendimiento del estado de git editando el archivo de configuración en el directorio .git y configurando ignore = dirty
en cualquier submódulo particularmente grande / pesado. Por ejemplo:
[submodule "mysubmodule"]
url = ssh://mysubmoduleURL
ignore = dirty
Perderá la conveniencia de un recordatorio de que hay cambios sin grabar en ninguno de los submódulos que puede haber olvidado, pero aún conservará la conveniencia principal de saber cuándo los submódulos no están sincronizados con el repositorio principal. Además, puede cambiar su directorio de trabajo al submódulo mismo y usar el estado de git dentro de él como de costumbre para ver más información. Vea esta pregunta para más detalles sobre lo que significa "sucio".
También estoy viendo este problema en un gran proyecto compartido a través de NFS.
Me tomó algo de tiempo descubrir la bandera -uno que se puede dar tanto para el estado de git commit como de git.
Lo que hace esta marca es desactivar la búsqueda de archivos sin seguimiento. Esto reduce significativamente el número de operaciones nfs. La razón es que para que git descubra archivos sin seguimiento tiene que buscar en todos los subdirectorios, por lo que si tienes muchos subdirectorios, esto te hará daño. Al deshabilitar que git busque archivos sin seguimiento, elimina todas estas operaciones NFS.
Combine esto con el indicador core.preloadindex y obtendrá un rendimiento razonable incluso en NFS.
git config --global core.preloadIndex true
Hizo el trabajo por mí. Verifique la documentación oficial here .