git-import natif distribué avec ClickHouse.
Les données générées fournissent un fichier tsv pour chacune des tables suivantes :
commits- commits avec statistiques.file_changes- fichiers modifiés dans chaque commit, avec des informations sur la modification et des statistiques.line_changes- chaque ligne modifiée dans chaque fichier modifié de chaque commit, avec toutes les informations sur la ligne ainsi que les informations sur la modification précédente de cette ligne.
commits- 7.8M - 266 051 lignesfile_changes- 53M - 266 051 lignesline_changes- 2.7G - 7 535 157 lignes
Génération des données
- Linux -
~/clickhouse git-import- 160 mins
Téléchargement et insertion des données
- ClickHouse (8 nov. 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 nov. 2022)
INSERT INTO SELECT et de la fonction s3. Par exemple, ci-dessous, nous insérons les fichiers ClickHouse dans chacune des tables correspondantes :
commits
Requêtes
git_clickhouse. Nous fournissons un lien vers cet environnement pour toutes les requêtes, en adaptant le nom de la base de données selon les besoins. Notez que les résultats sur play peuvent différer de ceux présentés ici en raison du moment de la collecte des données.
Historique d’un seul fichier
StorageReplicatedMergeTree.cpp. Comme les plus récents sont probablement les plus intéressants, nous les affichons d’abord.
play
Trouver les fichiers actifs actuels
dbms, libs, tests/testflows/ lors de leur renommage. Nous les excluons donc également.
play
old_path pour dresser la liste des fichiers supprimés à la suite d’un renommage. Nous faisons ensuite l’union avec la dernière opération pour chaque path. Enfin, nous filtrons cette liste pour ne conserver que les éléments dont l’événement final n’est pas un Delete.
play
--skip-paths 'generated\.cpp|^(contrib|docs?|website|libs/(libcityhash|liblz4|libdivide|libvectorclass|libdouble-conversion|libcpuid|libzstd|libfarmhash|libmetrohash|libpoco|libwidechar_width))/'
L’application de ce motif à git list-files renvoie 18155.
- Un renommage peut intervenir en même temps que d’autres modifications du fichier. Celles-ci sont répertoriées comme des événements distincts dans file_changes, mais avec le même horodatage. La fonction
argMaxn’a aucun moyen de les distinguer : elle choisit la première valeur. L’ordre naturel des insertions (le seul moyen de connaître le bon ordre) n’est pas conservé après l’union, si bien que des événements de modification peuvent être sélectionnés. Par exemple, ci-dessous, le fichiersrc/Functions/geometryFromColumn.ha subi plusieurs modifications avant d’être renommé ensrc/Functions/geometryConverters.h. Notre solution actuelle peut sélectionner un événement Modify comme dernière modification, ce qui conduit à conserversrc/Functions/geometryFromColumn.h.
- Historique des commits incomplet - événements de suppression manquants. Origine et cause à déterminer.
Lister les fichiers ayant le plus de modifications
Quel jour de la semaine les commits sont-ils généralement effectués ?
Historique du sous-répertoire/fichier - nombre de lignes, de commits et de contributeurs au fil du temps
toStartOfWeek — adaptez selon vos besoins.
play
Lignes de code les plus anciennes du dépôt
Fichiers à l’historique le plus long
Répartition des contributions à la documentation et au code au cours du mois
docs/ ont été exclues en raison d’un historique de commits très bruité. Les résultats de cette requête ne sont donc pas exacts.
Écrivons-nous plus de documentation à certains moments du mois, par exemple autour des dates de release ? Nous pouvons utiliser la fonction countIf pour calculer un ratio simple, et visualiser le résultat à l’aide de la fonction bar.
essayer
bar nous aident à visualiser ces répartitions :
essayer
sign = -1 indique une suppression de code. Nous excluons la ponctuation ainsi que l’insertion de lignes vides.
essayer
LIMIT BY à 3 afin d’obtenir, pour chaque auteur, les 3 personnes qui suppriment le plus de code, ce qui rend la visualisation plus variée.
Alexey aime manifestement supprimer le code des autres. Excluons-le pour obtenir une vue plus équilibrée de la suppression de code.
Quel contributeur a le pourcentage le plus élevé pour chaque jour de la semaine ?
Répartition de l’ancienneté du code dans l’ensemble du dépôt
Quels fichiers ont été réécrits le plus grand nombre de fois ?
path et commit_hash, puis en renvoyant le nombre de lignes ajoutées et supprimées. À l’aide d’une fonction de fenêtre, nous estimons la taille totale du fichier à chaque instant en effectuant une somme cumulative, et nous estimons l’impact de chaque modification sur la taille du fichier par lines added - lines removed. À partir de cette mesure, nous pouvons calculer le pourcentage du fichier ajouté ou supprimé pour chaque modification. Enfin, nous comptons, pour chaque fichier, le nombre de modifications qui constituent une réécriture, c.-à-d. (percent_add >= 0.5) AND (percent_delete >= 0.5) AND current_size > 50. Notez que nous exigeons des fichiers de plus de 50 lignes afin d’éviter que les premières contributions à un fichier soient comptées comme des réécritures. Cela évite également un biais en faveur des très petits fichiers, qui sont plus susceptibles d’être réécrits.
essayer
Quel jour de la semaine le code a-t-il le plus de chances de rester dans le dépôt ?
Fichiers triés par ancienneté moyenne du code
Qui a tendance à écrire davantage de tests / de code CPP / de commentaires ?
tests et calculer le ratio par rapport au nombre total de contributions.
Ici, nous limitons la requête aux utilisateurs ayant effectué plus de 20 modifications afin de nous concentrer sur les contributeurs réguliers et d’éviter un biais lié aux contributions ponctuelles.
essayer
Quel est le délai moyen avant qu’un code ne soit réécrit, et quelle est la médiane (demi-vie de l’obsolescence du code) ?
Quel est le pire moment pour écrire du code, c’est-à-dire celui où il a le plus de chances d’être réécrit ?
consecutive_day.
Les fonctions de tableau suivantes calculent ensuite, pour chaque auteur, sa plus longue séquence de 1 consécutifs. Tout d’abord, la fonction groupArray est utilisée pour regrouper toutes les valeurs consecutive_day d’un auteur. Ce tableau de 1 et de 0 est ensuite découpé sur les valeurs 0 en sous-tableaux. Enfin, nous calculons le sous-tableau le plus long.
play
Historique des commits d’un fichier, ligne par ligne
path contient le nouveau chemin du fichier, tandis que old_path indique son emplacement précédent, p. ex.
play
file_path_history('src/Storages/StorageReplicatedMergeTree.cpp'), nous parcourons récursivement l’historique des renommages, chaque fonction appelant le niveau suivant avec old_path. Les résultats sont ensuite concaténés à l’aide de arrayConcat.
Par exemple,
path.
Questions en suspens
Git blame
arrayFold ou arrayReduce, qui permettent de conserver un état à chaque itération.
Une solution approximative, suffisante pour une analyse à haut niveau, pourrait ressembler à ceci :