Contar o número de linhas em um repositório git


766

Como eu contaria o número total de linhas presentes em todos os arquivos em um repositório git?

git ls-files fornece uma lista de arquivos rastreados pelo git.

Estou procurando um comando para cattodos esses arquivos. Algo como

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

Respostas:


1140

xargs fará o que você quiser:

git ls-files | xargs cat | wc -l

Mas com mais informações e provavelmente melhor, você pode fazer:

git ls-files | xargs wc -l

11
Eu acho trivial; Que tal incluir apenas arquivos de código-fonte (por exemplo, * .cpp). Temos alguns arquivos bin comprometida :)
Daniel

39
Fique grep cpp |lá antes do xargs, então.
Carl Norum

35
Use git ls-files -z | xargs -0 wc -lse você tiver arquivos com espaços no nome.
mpontillo

34
Para incluir / excluir certos arquivos, use: git ls-files | grep -P ".*(hpp|cpp)" | xargs wc -londe a parte grep é qualquer perl regex que você deseja!
Gabriel

29
Se você estivesse interessado em apenas arquivos .java você pode usargit ls-files | grep "\.java$" | xargs wc -l
dseibert

352
git diff --stat 4b825dc642cb6eb9a060e54bf8d69288fbee4904

Isso mostra as diferenças da árvore vazia para a sua árvore de trabalho atual. O que acontece para contar todas as linhas da sua árvore de trabalho atual.

Para obter os números na sua árvore de trabalho atual, faça o seguinte:

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

Isso lhe dará uma string como 1770 files changed, 166776 insertions(+).


45
BTW, você pode obter esse hash executando git hash-object -t tree /dev/null.
ephemient

84
E ainda mais sucinta:git diff --stat `git hash-object -t tree /dev/null`
rpetrich

10
Essa é a melhor solução, já que isso não conta com arquivos binários, como arquivos ou imagens, contados na versão acima!
21313 BrainStone

31
+1 Gosto mais desta solução, pois os binários não são contados. Também estamos realmente interessados ​​na última linha da saída do git diff:git diff --stat `git hash-object -t tree /dev/null` | tail -1
Gabriele Petronella

31
em vez disso, use git diff --shortstat `git hash-object -t tree /dev/null` para obter a última linha, não é necessário rabo.
Jim Wolff

316

Se você deseja essa contagem porque deseja ter uma idéia do escopo do projeto, pode preferir a saída do CLOC ("Count Lines of Code"), que fornece uma descrição detalhada e insignificante de linhas de código por idioma.

cloc $(git ls-files)

(Esta linha é equivalente a git ls-files | xargs cloc. Ela usa sho recurso de $()substituição de comandos .)

Saída de amostra:

      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
-------------------------------------------------------------------------------

Você precisará instalar o CLOC primeiro. Você provavelmente pode instalar cloccom o seu gerenciador de pacotes - por exemplo, brew install cloccom o Homebrew .

cloc $(git ls-files)muitas vezes é uma melhoria cloc .. Por exemplo, o exemplo de saída acima com git ls-filesrelatórios 471 linhas de código. Para o mesmo projeto, cloc .reporta 456.279 linhas (e leva seis minutos para executar), porque pesquisa as dependências na node_modulespasta ignorada pelo Git .


4
O CLOC ignora algumas linguagens, como o TypeScript.
Marcelo Camargo

6
@MarceloCamargo neste momento typescript é suportado
Alexander

1
Para o iniciante, é melhor executar o "cloc DIRECTORY_WHERE_YOUR_GIT_IN" para calcular as linhas.
Shi

A descrição completa está aqui: github.com/AlDanial/cloc e os binários está aqui: github.com/AlDanial/cloc/releases/tag/v1.70
Peter Szanto

15
Você pode usar cloc --vcs gitesses dias, o que evita alguns casos extremos com arquivos com nomes incorretos (ou muitos deles).
seanf

56

Encontrei problemas em lotes git ls-files | xargs wc -lao lidar com um grande número de arquivos, em que a contagem de linhas será dividida em várias totallinhas.

Tomando uma dica da pergunta Por que o utilitário wc gera várias linhas com "total"? , Encontrei o seguinte comando para ignorar o problema:

wc -l $(git ls-files)

Ou se você quiser apenas examinar alguns arquivos, por exemplo, código:

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


Isso é ótimo, mas parece falhar nos caminhos que contêm espaços em branco. Existe uma maneira de resolver isso?
Lea Hayes

1
Teve problemas com o grep '. * \ .M' ao capturar arquivos binários como .mp3, .mp4. Teve mais sucesso com o uso do comando find para arquivos de código listawc -l $(git ls-files | find *.m *.h)
Tico Ballagas

3
@LeaHayes esta é uma forma: wc -l --files0-from=<(git ls-files -z). A <(COMMAND)sintaxe retorna o nome de um arquivo cujo conteúdo é o resultado COMMAND.
Buck

Obrigado, mas estou recebendo um erro quando tento esse comando 'não é possível fazer pipe para substituição de processo: Função não implementada wc: opção não reconhecida --files0-from ='. Alguma ideia?
Lea Hayes

1
@LeaHayes Eu vim com esse script que acho que funcionaria para você: `` #! / Bin / bash results = $ (git ls-files | xargs -d '\ n' wc -l) deixe grand_total = 0 para x em $ (eco "$ results" | egrep '[[: dígito:]] + total $'); faça grand_total + = $ (echo "$ x" | awk '{print $ 1}') done echo "$ {results}" echo "total geral: $ {grand_total}" ``
buck

45

A melhor solução, para mim, está enterrada nos comentários da resposta do @ ephemient. Estou apenas puxando aqui para que não passe despercebido. O crédito para isso deve ir para @FRoZeN (e @ephemient).

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

retorna o total de arquivos e linhas no diretório de trabalho de um repositório, sem nenhum ruído adicional. Como bônus, apenas o código-fonte é contado - arquivos binários são excluídos da contagem.

O comando acima funciona no Linux e OS X. A versão multiplataforma dele é

git diff --shortstat 4b825dc642cb6eb9a060e54bf8d69288fbee4904

Isso funciona no Windows também.

Para o registro, as opções para excluir linhas em branco,

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

não tem nenhum efeito quando usado com --shortstat. Linhas em branco são contadas.


1
git mktree </dev/nullou true|git mktreeou git mktree <&-ou :|git mktreepara os contadores de teclas entre nós :-) - uma árvore vazia vazia flutuando em torno do repositório não vai doer nada.
jthill

2
Para as pessoas querendo saber o que é que de hash fora do azul: stackoverflow.com/questions/9765453/...
Tejas Kale

19

Isso funciona a partir do cloc 1.68:

cloc --vcs=git


--vcsnão funcionou para mim, talvez tenha sido removido. cloc .enquanto no repositório git funcionou, OTOH.
Acdcjunior 10/07/19

13

Eu estava brincando com o cmder ( http://gooseberrycreative.com/cmder/ ) e queria contar as linhas de html, css, java e javascript. Enquanto algumas das respostas acima funcionaram, o orpadrão no grep não - eu encontrei aqui ( /unix/37313/how-do-i-grep-for-multiple-patterns ) que eu tinha escapar disso

Então é isso que eu uso agora:

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


2
Isso pareceu responder com pedaços para mim. Usar o grep em combinação com a solução de Justin Aquadro resultou bem para mim. wc -l $ (git ls-files | grep "\ (. html \ | .css \ | .js \ | .php \ | .json \ | .sh \) $")
Peter Mark

9

Eu uso o seguinte:

git grep ^ | wc -l

Ele pesquisa todos os arquivos versionados pelo git para o regex ^, que representa o início de uma linha, portanto, este comando fornece o número total de linhas!


3

Eu fiz isso:

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

isso funciona se você contar todos os arquivos de texto no repositório como os arquivos de seu interesse. Se alguns são considerados documentação, etc., um filtro de exclusão pode ser adicionado.


3

Esta ferramenta no github https://github.com/flosse/sloc pode fornecer a saída de maneira mais descritiva. Ele criará estatísticas do seu código-fonte:

  • linhas físicas
  • linhas de código (origem)
  • linhas com comentários
  • comentários de linha única
  • linhas com comentários em bloco
  • linhas misturadas com fonte e comentários
  • linhas vazias

1

Tentar:

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

no diretório / diretórios em questão


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

Ou:

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

0

Dependendo se você deseja ou não incluir arquivos binários, existem duas soluções.

  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 pode ler os arquivos usando quatro processos paralelos. Isso pode ser realmente útil se você estiver digitalizando repositórios muito grandes. Dependendo da capacidade da máquina, você pode aumentar o número de processos.

    -a, processa arquivos binários como texto (Incluir binário)
    -l '', mostra apenas nomes de arquivos em vez de linhas correspondentes (varre apenas arquivos não vazios)
    -I, não corresponde a padrões em arquivos binários (Excluir binário)
    --cache, procure no índice em vez de na árvore de trabalho (incluir arquivos não confirmados)

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.