Estadísticas de confirmación de culpa de Git
¿Cómo puedo "abusar" de la culpa (o de alguna función más adecuada, y/o en conjunto con los comandos del shell) para obtener una estadística de cuántas líneas (de código) hay actualmente en el repositorio que se originan en cada confirmador?
Salida de ejemplo:
Committer 1: 8046 Lines
Committer 2: 4378 Lines
Actualizar
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
Actualicé algunas cosas en el camino.
Para mayor comodidad, también puedes poner esto en su propio comando:
#!/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
almacene esto en algún lugar de su ruta o modifique su ruta y úselo como
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
Respuesta original
Si bien la respuesta aceptada funciona, es muy lenta.
$ 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
es casi instantáneo.
Para obtener una lista de los archivos actualmente rastreados, puede utilizar
git ls-tree --name-only -r HEAD
Esta solución evita llamadas file
para determinar el tipo de archivo y usa grep para hacer coincidir la extensión deseada por razones de rendimiento. Si se deben incluir todos los archivos, simplemente elimínelo de la línea.
grep -E '\.(cc|h|cpp|hpp|c)$' # for C/C++ files
grep -E '\.py$' # for Python files
Si los archivos pueden contener espacios, que son malos para los shells, puedes usar:
git ls-tree -z --name-only -r HEAD | egrep -Z -z '\.py'|xargs -0 ... # passes newlines as '\0'
Proporcione una lista de archivos (a través de una tubería) que se pueden usar xargs para llamar a un comando y distribuir los argumentos. Los comandos que permiten procesar varios archivos omiten el archivo -n1
. En este caso llamamos git blame --line-porcelain
y para cada llamada usamos exactamente 1 argumento.
xargs -n1 git blame --line-porcelain
Luego filtramos la salida para detectar apariciones de "autor", ordenamos la lista y contamos las líneas duplicadas por:
grep "^author "|sort|uniq -c|sort -nr
Nota
Otras respuestas en realidad filtran líneas que contienen solo espacios en blanco.
grep -Pzo "author [^\n]*\n([^\n]*\n){10}[\w]*[^\w]"|grep "author "
El comando anterior imprimirá los autores de las líneas que contengan al menos un carácter que no sea un espacio en blanco. También puede utilizar la coincidencia \w*[^\w#]
, que también excluirá las líneas en las que el primer carácter que no sea un espacio en blanco no sea un #
(comentario en muchos lenguajes de secuencias de comandos).
Escribí una joya llamada git-fame que podría resultar útil.
Instalación y uso:
$ gem install git_fame
$ cd /path/to/gitdir
$ git fame
Producción:
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 |
+----------------+-----+---------+-------+---------------------+
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
Explicación paso a paso:
Listar todos los archivos bajo control de versiones.
git ls-tree -r HEAD|sed -re 's/^.{53}//'
Reduzca la lista a solo archivos de texto
|while read filename; do file "$filename"; done|grep -E ': .*text'|sed -r -e 's/: .*//'
Git culpa a todos los archivos de texto, ignorando los cambios de espacios en blanco.
|while read filename; do git blame -w "$filename"; done
Saque los nombres de los autores.
|sed -r -e 's/.*\((.*)[0-9]{4}-[0-9]{2}-[0-9]{2} .*/\1/' -e 's/ +$//'
Ordene la lista de autores y haga que uniq cuente el número de líneas que se repiten consecutivamente
|sort|uniq -c
Salida de ejemplo:
1334 Maneater
1924 Another guy
37195 Brian Ruby
1482 Anna Lambda