214 votes

Statistiques sur les engagements de Git Blame

Comment puis-je "abuser" de blame (ou d'une autre fonction mieux adaptée, et/ou en conjonction avec des commandes shell) pour me donner une statistique du nombre de lignes (de code) actuellement dans le dépôt provenant de chaque committer ?

Exemple de sortie :

Committer 1: 8046 Lines
Committer 2: 4378 Lines

13 votes

Il devrait vraiment y avoir une commande intégrée pour cela... il existe des commandes pour des cas d'utilisation beaucoup moins courants.

0 votes

@CiroSantilli mais il est facile d'ajouter un shellscript invocable depuis git.

1 votes

C'est assez impressionnant code.google.com/p/gitinspector surtout si vous évaluez les travaux d'équipes d'étudiants (les grands projets ne sont pas concernés... il est lent parce qu'il rejette la faute sur chaque fichier individuel).

183voto

Alex Points 3973

Mise à jour

git ls-tree -r -z --name-only HEAD -- */*.c  | sed 's/^/.\//' | xargs -0 -n1 git blame \
--line-porcelain HEAD |grep -ae "^author "|sort|uniq -c|sort -nr

J'ai mis à jour certaines choses en cours de route.

Pour plus de commodité, vous pouvez également placer cette commande dans sa propre commande :

#!/bin/bash

# save as i.e.: git-authors and set the executable flag
git ls-tree -r -z --name-only HEAD -- $1 | sed 's/^/.\//' | xargs -0 -n1 git blame \
 --line-porcelain HEAD |grep -ae "^author "|sort|uniq -c|sort -nr

stockez-le quelque part dans votre chemin ou modifiez votre chemin et utilisez-le comme suit

  • git authors '*/*.c' # look for all files recursively ending in .c
  • git authors '*/*.[ch]' # look for all files recursively ending in .c or .h
  • git authors 'Makefile' # just count lines of authors in the Makefile

Réponse originale

Bien que la réponse acceptée fasse l'affaire, elle est très lente.

$ git ls-tree --name-only -z -r HEAD|egrep -z -Z -E '\.(cc|h|cpp|hpp|c|txt)$' \
  |xargs -0 -n1 git blame --line-porcelain|grep "^author "|sort|uniq -c|sort -nr

est presque instantanée.

Pour obtenir une liste des fichiers actuellement suivis, vous pouvez utiliser

git ls-tree --name-only -r HEAD

Cette solution évite d'appeler file pour déterminer le type de fichier et utilise grep pour faire correspondre l'extension souhaitée pour des raisons de performance. Si tous les fichiers doivent être inclus, il suffit de supprimer cette option de la ligne.

grep -E '\.(cc|h|cpp|hpp|c)$' # for C/C++ files
grep -E '\.py$'               # for Python files

si les fichiers peuvent contenir des espaces, qui sont mauvais pour les shells que vous pouvez utiliser :

git ls-tree -z --name-only -r HEAD | egrep -Z -z '\.py'|xargs -0 ... # passes newlines as '\0'

En donnant une liste de fichiers (via un pipe), on peut utiliser xargs pour appeler une commande et distribuer les arguments. Les commandes qui permettent de traiter plusieurs fichiers omettent les arguments de xargs. -n1 . Dans ce cas, nous appelons git blame --line-porcelain et pour chaque appel nous utilisons exactement 1 argument.

xargs -n1 git blame --line-porcelain

Nous filtrons ensuite la sortie pour les occurrences de "auteur", trions la liste et comptons les lignes en double :

grep "^author "|sort|uniq -c|sort -nr

Note

D'autres réponses filtrent en fait les lignes qui ne contiennent que des espaces.

grep -Pzo "author [^\n]*\n([^\n]*\n){10}[\w]*[^\w]"|grep "author "

La commande ci-dessus va imprimer les auteurs des lignes contenant au moins un caractère non blanc. Vous pouvez également utiliser match \w*[^\w#] ce qui exclura également les lignes où le premier caractère non espace n'est pas un # (commentaire dans de nombreux langages de script).

1 votes

De belles améliorations ! Je n'avais pas réalisé, au moment où j'ai écrit ceci, que l'on pouvait envoyer à git la faute de plusieurs arguments de fichier

2 votes

@nilbus : vous ne pouvez pas. echo "a\nb\nc"|xargs -n1 cmd s'étendra à cmd a; cmd b; cmd d

3 votes

--line-porcelain ne semble plus fonctionner (git 1.7.5.4) utilisez plutôt --porcelain

130voto

Oleander Points 2978

J'ai écrit une gemme appelée git-fame qui pourraient être utiles.

Installation et utilisation :

  1. $ gem install git_fame
  2. $ cd /path/to/gitdir
  3. $ git fame

Salida:

Statistics based on master
Active files: 21
Active lines: 967
Total commits: 109

Note: Files matching MIME type image, binary has been ignored

+----------------+-----+---------+-------+---------------------+
| name           | loc | commits | files | distribution (%)    |
+----------------+-----+---------+-------+---------------------+
| Linus Oleander | 914 | 106     | 21    | 94.5 / 97.2 / 100.0 |
| f1yegor        | 47  | 2       | 7     |  4.9 /  1.8 / 33.3  |
| David Selassie | 6   | 1       | 2     |  0.6 /  0.9 /  9.5  |
+----------------+-----+---------+-------+---------------------+

1 votes

Ne fonctionne pas non plus sous Windows : No such file or directory - /usr/bin/env

6 votes

+1 enfin 1 qui fonctionne et qui semble donner des chiffres raisonnables, le reste des lignes de commande ne fonctionne pas sur OSX en raison de l'incompatibilité des utils ou donne des chiffres minuscules sur mon repo. Ceci sous OSX et ruby 1.9.3 (brew).

11 votes

Ne sois pas bête, @tcaswell. Ce n'est pas du spam que de pointer vers quelque chose d'utile, même si c'est vous qui avez écrit ce quelque chose.

56voto

nilbus Points 5476
git ls-tree -r HEAD|sed -re 's/^.{53}//'|while read filename; do file "$filename"; done|grep -E ': .*text'|sed -r -e 's/: .*//'|while read filename; do git blame -w "$filename"; done|sed -r -e 's/.*\((.*)[0-9]{4}-[0-9]{2}-[0-9]{2} .*/\1/' -e 's/ +$//'|sort|uniq -c

Explication étape par étape :

Liste de tous les fichiers sous contrôle de version

git ls-tree -r HEAD|sed -re 's/^.{53}//'

Réduire la liste aux seuls fichiers texte

|while read filename; do file "$filename"; done|grep -E ': .*text'|sed -r -e 's/: .*//'

Git blâme tous les fichiers texte, en ignorant les changements d'espaces blancs

|while read filename; do git blame -w "$filename"; done

Sortez les noms des auteurs

|sed -r -e 's/.*\((.*)[0-9]{4}-[0-9]{2}-[0-9]{2} .*/\1/' -e 's/ +$//'

Triez la liste des auteurs, et demandez à uniq de compter le nombre de lignes qui se répètent consécutivement.

|sort|uniq -c

Exemple de sortie :

   1334 Maneater
   1924 Another guy
  37195 Brian Ruby
   1482 Anna Lambda

1 votes

Il semble que j'aie une sed la mienne ne comprend pas la -r et a des problèmes avec les regex (se plaint de parens déséquilibrés, même lorsque je supprime le surplus ( ).

7 votes

Jamais de la vie, sudo brew install gnu-sed l'a résolu. Cela fonctionne comme un charme !

5 votes

Ou port install gsed pour les utilisateurs de MacPorts.

6voto

gtd Points 7062

La solution d'Erik était géniale, mais j'ai eu quelques problèmes avec les diacritiques (malgré mes LC_* les variables d'environnement étant ostensiblement définies correctement) et les fuites de bruit sur les lignes de code qui contenaient réellement des dates. Mon sed-fu est pauvre, donc j'ai fini avec ce snippet frankenstein avec ruby dedans, mais il fonctionne pour moi sans problème sur 200.000+ LOC, et il trie les résultats :

git ls-tree -r HEAD | gsed -re 's/^.{53}//' | \
while read filename; do file "$filename"; done | \
grep -E ': .*text' | gsed -r -e 's/: .*//' | \
while read filename; do git blame "$filename"; done | \
ruby -ne 'puts $1.strip if $_ =~ /^\w{8} \((.*?)\s*\d{4}-\d{2}-\d{2}/' | \
sort | uniq -c | sort -rg

Notez également gsed au lieu de sed parce que c'est le binaire que l'homebrew installe, laissant le système sed intact.

5voto

marcog Points 39356

git shortlog -sn

Ceci montrera une liste de commits par auteur.

17 votes

Cela renvoie le nombre de commits par auteur, pas le nombre de lignes.

0 votes

Très utile pour déterminer les principaux contributeurs à un projet/répertoire/fichier.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X