Cuenta el número de líneas en un repositorio git

766

¿Cómo contaría el número total de líneas presentes en todos los archivos en un repositorio git?

git ls-files me da una lista de archivos rastreados por git.

Estoy buscando un comando para cattodos esos archivos. Algo como

git ls-files | [cat all these files] | wc -l
Dogbert
fuente

Respuestas:

1141

xargs hará lo que quieras:

git ls-files | xargs cat | wc -l

Pero con más información y probablemente mejor, puede hacer:

git ls-files | xargs wc -l
Carl Norum
fuente
11
Supongo trivial; ¿Qué tal incluir solo archivos de código fuente (por ejemplo, * .cpp)? Tenemos algunos archivos bin comprometidos :)
Daniel
39
Quédate grep cpp |ahí antes xargs, entonces.
Carl Norum
35
Úselo git ls-files -z | xargs -0 wc -lsi tiene archivos con espacios en el nombre.
mpontillo
34
Para incluir / excluir el uso de ciertos archivos: ¡ git ls-files | grep -P ".*(hpp|cpp)" | xargs wc -ldonde la parte grep es cualquier expresión regular perl que desee!
Gabriel
29
Si solo estaba interesado en archivos .java, puede usarlosgit ls-files | grep "\.java$" | xargs wc -l
dseibert
352
git diff --stat 4b825dc642cb6eb9a060e54bf8d69288fbee4904

Esto muestra las diferencias del árbol vacío a su árbol de trabajo actual. Lo que sucede para contar todas las líneas en su árbol de trabajo actual.

Para obtener los números en su árbol de trabajo actual, haga esto:

git diff --shortstat `git hash-object -t tree /dev/null`

Te dará una cadena como 1770 files changed, 166776 insertions(+).

efímero
fuente
45
Por cierto, puedes obtener ese hash ejecutando git hash-object -t tree /dev/null.
Ephemient
84
Y aún más sucinto:git diff --stat `git hash-object -t tree /dev/null`
rpetrich
10
¡Esta es la mejor solución ya que no cuenta los archivos binarios como archivos o imágenes que se cuentan en la versión anterior!
BrainStone
31
+1 Me gusta más esta solución ya que los binarios no se cuentan. También estamos realmente interesados ​​en la última línea de la salida de git diff:git diff --stat `git hash-object -t tree /dev/null` | tail -1
Gabriele Petronella
31
en lugar de usar git diff --shortstat `git hash-object -t tree /dev/null` para obtener la última línea, la cola no es necesaria.
Jim Wolff
316

Si desea este recuento porque quiere tener una idea del alcance del proyecto, puede preferir la salida de CLOC ("Contar líneas de código"), que le ofrece un desglose de líneas de código significativas e insignificantes por idioma.

cloc $(git ls-files)

(Esta línea es equivalente a git ls-files | xargs cloc. Utiliza shla función de $()sustitución de comandos ).

Salida de muestra:

      20 text files.
      20 unique files.                              
       6 files ignored.

http://cloc.sourceforge.net v 1.62  T=0.22 s (62.5 files/s, 2771.2 lines/s)
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
Javascript                       2             13            111            309
JSON                             3              0              0             58
HTML                             2              7             12             50
Handlebars                       2              0              0             37
CoffeeScript                     4              1              4             12
SASS                             1              1              1              5
-------------------------------------------------------------------------------
SUM:                            14             22            128            471
-------------------------------------------------------------------------------

Tendrás que instalar CLOC primero. Probablemente pueda instalarlo cloccon su administrador de paquetes, por ejemplo, brew install cloccon Homebrew .

cloc $(git ls-files)A menudo es una mejora cloc .. Por ejemplo, la salida de muestra anterior con git ls-filesinformes 471 líneas de código. Para el mismo proyecto, cloc .reporta la friolera de 456,279 líneas (y tarda seis minutos en ejecutarse), porque busca las dependencias en la node_modulescarpeta ignorada de Git .

Rory O'Kane
fuente
44
CLOC ignora algunos lenguajes, como TypeScript.
Marcelo Camargo
66
@MarceloCamargo en este momento es compatible con TypeScript
Alexander
1
Para el principiante, es mejor ejecutar "cloc DIRECTORY_WHERE_YOUR_GIT_IN" para calcular las líneas.
Shi
La descripción completa está aquí: github.com/AlDanial/cloc y los binarios están aquí: github.com/AlDanial/cloc/releases/tag/v1.70
Peter Szanto
15
Puede usar cloc --vcs gitestos días, lo que evita algunos casos extremos con archivos mal nombrados (o demasiados).
seanf
56

Me he encontrado con problemas de procesamiento por lotes git ls-files | xargs wc -lal tratar con grandes cantidades de archivos, donde los recuentos de líneas se dividirán en varias totallíneas.

Tomando un consejo de la pregunta ¿Por qué la utilidad wc genera múltiples líneas con "total"? , Encontré el siguiente comando para evitar el problema:

wc -l $(git ls-files)

O si solo desea examinar algunos archivos, por ejemplo, el código:

wc -l $(git ls-files | grep '.*\.cs')

Justin Aquadro
fuente
Esto es genial, pero parece fallar para los caminos que contienen espacios en blanco. ¿Hay alguna manera de resolver eso?
Lea Hayes
1
Tuve problemas con grep '. * \. M' al recoger archivos binarios como .mp3, .mp4. Tuve más éxito con el uso del comando find para enumerar archivos de códigowc -l $(git ls-files | find *.m *.h)
Tico Ballagas
3
@LeaHayes esta es una manera: wc -l --files0-from=<(git ls-files -z). La <(COMMAND)sintaxis devuelve el nombre de un archivo cuyo contenido es el resultado de COMMAND.
dinero el
@buck Gracias, pero recibo un error cuando intento ese comando 'no se puede hacer la tubería para la sustitución del proceso: Función no implementada wc: opción no reconocida --files0-from ='. ¿Algunas ideas?
Lea Hayes
1
@LeaHayes Se me ocurrió esta secuencia de comandos que creo que funcionaría para usted: `` `# # / bin / bash results = $ (git ls-files | xargs -d '\ n' wc -l) let grand_total = 0 for x en $ (echo "$ resultados" | egrep '[[: dígito:]] + total $'); deje que grand_total + = $ (echo "$ x" | awk '{print $ 1}') done echo "$ {results}" echo "gran total: $ {grand_total}" `` `
compre el
45

La mejor solución, para mí de todos modos, está enterrada en los comentarios de la respuesta de @ ephemient. Solo lo estoy jalando aquí para que no pase desapercibido. El crédito para esto debe ir a @FRoZeN (y @ephemient).

git diff --shortstat `git hash-object -t tree /dev/null`

devuelve el total de archivos y líneas en el directorio de trabajo de un repositorio, sin ningún ruido adicional. Como beneficio adicional, solo se cuenta el código fuente: los archivos binarios se excluyen de la cuenta.

El comando anterior funciona en Linux y OS X. La versión multiplataforma es

git diff --shortstat 4b825dc642cb6eb9a060e54bf8d69288fbee4904

Eso también funciona en Windows.

Para el registro, las opciones para excluir líneas en blanco,

  • -w/ --ignore-all-space,
  • -b/ --ignore-space-change,
  • --ignore-blank-lines,
  • --ignore-space-at-eol

no tiene ningún efecto cuando se usa con --shortstat. Se cuentan las líneas en blanco.

hashchange
fuente
1
git mktree </dev/nullo true|git mktreeo git mktree <&-o :|git mktreepara los contadores de pulsaciones de teclas entre nosotros :-) - un árbol vacío de repuesto flotando alrededor del repositorio no va a doler nada.
jthill
2
Para las personas que se preguntan qué es ese hash de la nada
Tejas Kale
19

Esto funciona a partir del cloc 1.68:

cloc --vcs=git

kes
fuente
--vcsno funcionó para mí, tal vez fue eliminado. cloc .mientras que en el repositorio de git funcionó, OTOH.
acdcjunior
13

Estaba jugando con cmder ( http://gooseberrycreative.com/cmder/ ) y quería contar las líneas de html, css, java y javascript. Si bien algunas de las respuestas anteriores funcionaron, el orpatrón en grep no funcionó: encontré aquí ( /unix/37313/how-do-i-grep-for-multiple-patterns ) que tenía para escapar de ella

Entonces esto es lo que uso ahora:

git ls-files | grep "\(.html\|.css\|.js\|.java\)$" | xargs wc -l

Michail Michailidis
fuente
2
Esto pareció responder con trozos para mí. Usar su grep en combinación con la solución de Justin Aquadro resultó bien para mí. wc -l $ (git ls-files | grep "\ (. html \ | .css \ | .js \ | .php \ | .json \ | .sh \) $")
Peter Mark
9

Yo uso lo siguiente:

git grep ^ | wc -l

Esto busca en todos los archivos versionados por git para la expresión regular ^, que representa el comienzo de una línea, por lo que este comando da el número total de líneas.

Christopher Shroba
fuente
3

Hice esto:

git ls-files | xargs file | grep "ASCII" | cut -d : -f 1 | xargs wc -l

esto funciona si cuenta todos los archivos de texto en el repositorio como los archivos de interés. Si algunos se consideran documentación, etc., se puede agregar un filtro de exclusión.

Sasha Pachev
fuente
3

Esta herramienta en github https://github.com/flosse/sloc puede proporcionar la salida de manera más descriptiva. Creará estadísticas de su código fuente:

  • lineas fisicas
  • líneas de código (fuente)
  • líneas con comentarios
  • comentarios de una sola línea
  • líneas con comentarios de bloque
  • líneas mezcladas con fuente y comentarios
  • lineas vacias
amor
fuente
1

Tratar:

find . -type f -name '*.*' -exec wc -l {} + 

en el directorio / directorios en cuestión

Theos
fuente
0
: | git mktree | git diff --shortstat --stdin

O:

git ls-tree @ | sed '1i\\' | git mktree --batch | xargs | git diff-tree --shortstat --stdin

fuente
0

Dependiendo de si desea o no incluir archivos binarios, hay dos soluciones.

  1. git grep --cached -al '' | xargs -P 4 cat | wc -l
  2. git grep --cached -Il '' | xargs -P 4 cat | wc -l

    "xargs -P 4" significa que puede leer los archivos usando cuatro procesos paralelos. Esto puede ser realmente útil si está escaneando repositorios muy grandes. Dependiendo de la capacidad de la máquina, puede aumentar el número de procesos.

    -a, procesar archivos binarios como texto (Incluir binario)
    -l '', mostrar solo nombres de archivo en lugar de líneas coincidentes (Escanear solo archivos no vacíos)
    -I, no hacer coincidir patrones en archivos binarios (Excluir binario) - en
    caché, buscar en el índice en lugar de en el árbol de trabajo (Incluir archivos no confirmados)

Bharat
fuente