Existe uma maneira de ter git show lines adicionadas, linhas alteradas e linhas removidas?

110

"git diff --stat" e "git log --stat" mostram resultados como:

$ git diff -C --stat HEAD c9af3e6136e8aec1f79368c2a6164e56bf7a7e07
 app/controllers/application_controller.rb |   34 +++-------------------------
 1 files changed, 4 insertions(+), 30 deletions(-)

Mas o que realmente aconteceu naquele commit foi que 4 linhas foram alteradas e 26 linhas foram excluídas, o que é diferente de adicionar 4 linhas e excluir 30.

Existe alguma maneira de obter os LOCs delta (26 neste caso)? Eu realmente não me importo em diferenciar as linhas adicionadas ou removidas.

Juan Alonso
fonte

Respostas:

127

Você pode usar:

git diff --numstat

para obter informações de diferenças numéricas.

No que diz respeito a separar a modificação de um par adicionar e remover, --word-diffpode ajudar. Você pode tentar algo assim:

MOD_PATTERN='^.+(\[-|\{\+).*$' \
ADD_PATTERN='^\{\+.*\+\}$' \
REM_PATTERN='^\[-.*-\]$' \
git diff --word-diff --unified=0 | sed -nr \
    -e "s/$MOD_PATTERN/modified/p" \
    -e "s/$ADD_PATTERN/added/p" \
    -e "s/$REM_PATTERN/removed/p" \
    | sort | uniq -c

É um pouco prolixo, então você pode querer analisá-lo em seu próprio script.

quorniano
fonte
2
Obrigado quornian, mas numstat dá exatamente as mesmas informações que stat, adições e exclusões.
Juan Alonso
Atualizei minha resposta para incluir um exemplo de uso de --word-diff. Isso pode ser mais útil.
quornian 01 de
14
A saída de git diff --numstaté dividida por arquivo. Para ver o total adicionado / removido para o diff, você pode canalizá-lo para awk:git diff --numstat | awk '{ added += $1; removed += $2 } END { print "+" added " -" removed }'
hughes
15
@hughes Uma maneira mais simples de obter as mesmas informações seria git diff --shortstat. Na minha experiência, é equivalente a acumular a produção de git diff --numstat.
klaus triendl
1
Além disso, FWIW para ver as estatísticas das mudanças em etapas, basta adicionar--cached
xlm
65
  1. Se você quiser saber as linhas adicionadas / alteradas / deletadas por um commit com id commit-id, você pode usar

    git show commit-id --stat
    

    ou

    git diff commit-id-before commit-id --stat
    
  2. Se você quiser saber as linhas adicionadas / alteradas / excluídas por um commit de intervalo, você pode usar

    git diff commit-id1 commit-id2 --stat
    
  3. Se você quiser saber as linhas adicionadas / alteradas / deletadas por cada commit, você pode usar

    git log --stat
    
yhluo
fonte
Essa solução não responde à pergunta, "git --stat" conta uma única linha modificada como "1 inserção e 1 exclusão". A questão pergunta como obter "1 alterado".
Juan Alonso
6

Se todos os seus arquivos forem testados para confirmação, veja o que está --numstatacontecendo assim:

git diff --numstat HEAD~
Falieson
fonte
4

git usa diff "unificado", que apenas adiciona e exclui linhas, como o formato diff. Você tem que fazer algo externo para obter uma comparação que mostre adicionar, excluir e alterar informações.

https://wiki.postgresql.org/wiki/Working_with_Git#Context_diffs_with_Git fornece links para um script que permite a execução regular de "diff" antigo - e a partir disso você pode gerar uma saída de diff de "contexto" . O diff de contexto mostra linhas adicionadas, removidas e alteradas, o que deve permitir que você obtenha os dados que deseja.

Daniel Pittman
fonte
3

Você pode usar diffstatpara mostrar o número de linhas modificadas. Por exemplo:

git diff HEAD c9af3e6136e8aec1f79368c2a6164e56bf7a7e07 | diffstat -C -m

A -Copção é obter saída colorida; a -mopção é mostrar o número de linhas modificadas. Saída de amostra:

 app/controllers/application_controller.rb |   30 -------------------!!!
 1 files changed, 0 insertions(+), 26 deletions(-), 4 modifications(!)

A contagem para o número de linhas modificadas é aproximada, como man diffstatdiz:

-m mescla as contagens de inserção / exclusão de cada "pedaço" do arquivo de patch para aproximar a contagem das linhas modificadas.

Uma diferença importante entre git diff --state diffstat: diffstatnão mostra movimentos / renomeações de arquivos (por exemplo app/{a.rb => b.rb}).

Fluxo
fonte