git-import incluida con ClickHouse.
Los datos generados incluyen un archivo tsv para cada una de las siguientes tablas:
commits- commits con estadísticas.file_changes- archivos modificados en cada commit, con información sobre el cambio y estadísticas.line_changes- cada línea modificada en cada archivo modificado de cada commit, con información completa sobre la línea y sobre el cambio anterior de esa línea.
commits- 7.8M - 266,051 filasfile_changes- 53M - 266,051 filasline_changes- 2.7G - 7,535,157 filas
Generación de datos
- Linux -
~/clickhouse git-import- 160 min
Descarga e inserción de datos
- ClickHouse (8 de noviembre de 2022)
- https://datasets-documentation.s3.amazonaws.com/github/commits/clickhouse/commits.tsv.xz - 2.5 MB
- https://datasets-documentation.s3.amazonaws.com/github/commits/clickhouse/file_changes.tsv.xz - 4.5MB
- https://datasets-documentation.s3.amazonaws.com/github/commits/clickhouse/line_changes.tsv.xz - 127.4 MB
- Linux (8 de noviembre de 2022)
INSERT INTO SELECT y la función s3. Por ejemplo, a continuación insertamos los archivos de ClickHouse en sus respectivas tablas:
commits
Consultas
git_clickhouse. Proporcionamos un enlace a este entorno para todas las consultas, adaptando el nombre de la base de datos según sea necesario. Ten en cuenta que los resultados en play pueden variar con respecto a los que se presentan aquí debido a diferencias en el momento de la recopilación de los datos.
Historial de un solo archivo
StorageReplicatedMergeTree.cpp. Como probablemente sean los más interesantes, los ordenamos empezando por los más recientes.
play
Encontrar los archivos activos actuales
dbms, libs y tests/testflows/ durante sus cambios de nombre. Por ello, también los excluimos.
play
old_path para obtener una lista de los archivos eliminados como resultado del cambio de nombre. Luego, combinamos esto con la última operación de cada path. Por último, filtramos esta lista para quedarnos con aquellos en los que el evento final no es un Delete.
play
--skip-paths 'generated\.cpp|^(contrib|docs?|website|libs/(libcityhash|liblz4|libdivide|libvectorclass|libdouble-conversion|libcpuid|libzstd|libfarmhash|libmetrohash|libpoco|libwidechar_width))/'
Al aplicar este patrón a git list-files, el resultado es 18155.
- Un cambio de nombre puede producirse junto con otras modificaciones del archivo. Estas se registran como eventos independientes en file_changes, pero con la misma hora. La función
argMaxno tiene forma de distinguirlos: elige el primer valor. El orden natural de las inserciones (el único medio para conocer el orden correcto) no se conserva en la unión, por lo que pueden seleccionarse eventos de modificación. Por ejemplo, a continuación, el archivosrc/Functions/geometryFromColumn.htiene varias modificaciones antes de renombrarse asrc/Functions/geometryConverters.h. Nuestra solución actual puede elegir un evento Modify como el cambio más reciente, lo que hace que se conservesrc/Functions/geometryFromColumn.h.
- Historial de commits incompleto: faltan eventos de eliminación. El origen y la causa aún están por determinar.
Lista de archivos con más modificaciones
¿Qué día de la semana suelen realizarse los commits?
Historial del subdirectorio/archivo: número de líneas, commits y colaboradores a lo largo del tiempo
toStartOfWeek; adáptela según sea necesario.
play
Las líneas de código más antiguas del repositorio
Archivos con el historial más extenso
Distribución de colaboradores entre documentación y código a lo largo del mes
docs/ debido a un historial de commits muy desordenado. Por lo tanto, los resultados de esta consulta no son precisos.
¿Escribimos más documentación en determinados momentos del mes, por ejemplo, en torno a las fechas de lanzamiento? Podemos usar la función countIf para calcular una proporción simple y visualizar el resultado con la función bar.
probar
bar nos ayudan a visualizar estas distribuciones:
probar
sign = -1 indica una eliminación de código. Excluimos la puntuación y la inserción de líneas vacías.
play
LIMIT BY a 3 para obtener los 3 autores que más código eliminan de cada autor y así mejorar la variedad de la visualización.
Está claro que a Alexey le gusta eliminar el código de otras personas. Excluyámoslo para obtener una visión más equilibrada de la eliminación de código.
¿Quién aporta el mayor porcentaje por día de la semana?
Distribución de la antigüedad del código en el repositorio
¿Qué archivos se reescribieron más veces?
path y commit_hash, y devolvemos el número de líneas añadidas y eliminadas. Mediante una función de ventana, estimamos el tamaño total del archivo en cada momento realizando una suma acumulada y calculando el impacto de cada cambio en el tamaño del archivo como lines added - lines removed. A partir de esta métrica, podemos calcular el porcentaje del archivo que se ha añadido o eliminado en cada cambio. Por último, contamos el número de cambios de archivo que constituyen una reescritura por archivo, es decir, (percent_add >= 0.5) AND (percent_delete >= 0.5) AND current_size > 50. Ten en cuenta que exigimos que los archivos tengan más de 50 líneas para evitar que las contribuciones iniciales a un archivo se contabilicen como una reescritura. Esto también evita un sesgo hacia archivos muy pequeños, que pueden ser más propensos a reescribirse.
play
¿Qué día de la semana tiene el código más probabilidades de permanecer en el repositorio?
Archivos ordenados por la antigüedad media del código
¿Quién suele escribir más tests / código en C++ / comentarios?
tests y calcular la proporción con respecto al total de contribuciones.
Aquí limitamos la consulta a usuarios con más de 20 cambios para centrarnos en quienes hacen commits con regularidad y evitar sesgos debidos a contribuciones puntuales.
play
¿Cuál es el tiempo promedio antes de que el código se reescriba y cuál es la mediana (vida media de la degradación del código)?
¿Cuándo es peor escribir código, en el sentido de que tenga más probabilidades de reescribirse?
consecutive_day.
A continuación, nuestras funciones de array calculan la secuencia más larga de unos consecutivos de cada autor. Primero, se usa la función groupArray para recopilar todos los valores de consecutive_day de un autor. Luego, este array de 1 y 0 se divide en subarrays en los valores 0. Por último, calculamos el subarray más largo.
probar
Historial de commits línea por línea de un archivo
path se establece con la nueva ruta del archivo y old_path representa la ubicación anterior, por ejemplo.
play
file_path_history('src/Storages/StorageReplicatedMergeTree.cpp'), recorremos de forma recursiva el historial de cambios de nombre; cada función llama al siguiente nivel con old_path. Los resultados se combinan con arrayConcat.
Por ejemplo,
path.
Cuestiones pendientes
Git blame
arrayFold o arrayReduce, que permiten conservar el estado en cada iteración.
Una solución aproximada, suficiente para un análisis de alto nivel, podría ser algo así: