W3docs

git diff

Saiba como usar o comando git diff para visualizar alterações, comparar ficheiros e destacar diferenças entre commits e branches.

O que faz o git diff

O comando git diff mostra exatamente o que mudou, linha por linha, entre duas fontes do seu projeto. Ele recebe dois conjuntos de dados e imprime as diferenças entre eles como um patch.

Essas duas fontes podem ser qualquer par de: sua árvore de trabalho (os ficheiros que você está editando agora), a área de staging (o índice, o que o git add capturou), e qualquer snapshot confirmado. Como todos os outros comandos Git apenas informam que algo mudou, o git diff é a ferramenta que diz o que mudou antes de você fazer o stage ou o commit.

É comumente usado em conjunto com git status e git log para inspecionar o estado de um repositório git: o git status lista quais ficheiros foram alterados, e o git diff mostra o conteúdo dessas alterações.

gitdiff

Quais duas fontes são comparadas

A forma do comando decide o que é comparado:

ComandoCompara
git diffÁrvore de trabalho vs. área de staging (alterações não staged)
git diff --stagedÁrea de staging vs. último commit (o que o git commit registaria)
git diff HEADÁrvore de trabalho vs. último commit (todas as alterações não confirmadas)
git diff <commit> <commit>Um commit vs. outro
git diff <branch> <branch>As pontas de dois branches

Um git diff simples mostra apenas o que você ainda não fez stage com git add. Este é o erro mais comum: se você já executou o git add, o git diff parece vazio mesmo que haja edições — use git diff --staged para vê-las.

Lendo a saída do diff

Um diff tem várias partes distintas. As secções abaixo constroem uma e explicam cada linha.

Formato de saída bruto

Veja os comandos abaixo para criar um repositório simples:

mkdir test_repo
cd test_repo
touch test.txt
echo "this is a git diff test example" > test.txt
git init .
#Initialized empty Git repository in /Users/kev/code/test/.git/
git add test.txt
git commit -am "add diff test file"
#[master (root-commit) 9e2dcac] add diff test file
#1 file changed, 1 insertion(+)
#create mode 100644 test.txt

Se quiser que o git diff produza saída, você deve alterar o conteúdo de test.txt após confirmá-lo. Execute o seguinte comando:

echo "this is a diff example" > test.txt

Só agora podemos visualizar um diff e discutir a saída. Executar git diff produzirá o seguinte:

diff --git a/test.txt b/test.txt
index 6b0c6cf..b37e70a 100644
--- a/test.txt
+++ b/test.txt
@@ -1 +1 @@
-this is a git diff test example
+this is a diff example

Fontes de entrada do diff

A primeira linha nomeia as duas fontes sendo comparadas. Aqui a/test.txt (a versão "antes") e b/test.txt (a versão "depois") são passadas ao diff. Os prefixos a/ e b/ marcam sempre os dois lados, mesmo quando é o mesmo ficheiro.

diff --git a/test.txt b/test.txt

Metadados

Esta linha mostra metadados internos do Git. Os dois números são os hashes de objeto (blob) abreviados do ficheiro antes e depois da alteração, e 100644 é o modo do ficheiro (um ficheiro regular, não executável).

index 6b0c6cf..b37e70a 100644

Símbolos para alterações

Estas linhas atribuem um símbolo a cada fonte de entrada do diff. As linhas de a/test.txt (o original) são marcadas com ---, e as linhas de b/test.txt (a nova versão) são marcadas com +++.

--- a/test.txt
+++ b/test.txt

Chunks do diff

Um diff não mostra o ficheiro inteiro — apenas as regiões modificadas. Cada uma dessas regiões é chamada de chunk (ou hunk). Os chunks incluem algumas linhas inalteradas de contexto circundante para que você possa ver onde a alteração se situa.

@@ -1 +1 @@
-this is a git diff test example
+this is a diff example

A primeira linha é o cabeçalho do chunk, envolto em símbolos @@. Ele resume os intervalos de linhas afetadas: -1 significa "começando na linha 1 do ficheiro antigo" e +1 significa "começando na linha 1 do ficheiro novo". Abaixo do cabeçalho, um - inicial marca uma linha removida e um + inicial marca uma linha adicionada. Uma linha modificada aparece, portanto, como uma remoção seguida de uma adição.

Flags comuns

O Git oferece diversas flags úteis para diferentes fluxos de trabalho:

  • --staged (ou --cached): Compara as alterações staged no índice com o commit HEAD — o que um git commit registaria.
  • --stat: Mostra um resumo condensado dos ficheiros alterados (inserções/deleções por ficheiro) em vez do diff completo.
  • --name-only: Exibe apenas os nomes dos ficheiros alterados.
  • --name-status: Como --name-only, mas prefixia cada ficheiro com sua letra de status (M modificado, A adicionado, D deletado).
  • -w (ou --ignore-all-space): Ignora alterações apenas de espaço em branco, o que é útil quando a reindentação oculta as edições reais.

Por exemplo, para obter uma visão geral rápida de quanto cada ficheiro mudou:

git diff --stat
# test.txt | 2 +-
# 1 file changed, 1 insertion(+), 1 deletion(-)

Destacando alterações

Para edições ao nível de linha, a saída padrão pode ser ruidosa, pois o Git mostra uma linha removida completa e uma linha adicionada completa mesmo quando apenas uma palavra difere. As duas ferramentas abaixo destacam as partes exatas que mudaram.

git diff --color-words

A primeira forma é um modo especial integrado ao git diff: --color-words. Ele tokeniza as linhas adicionadas e removidas por espaço em branco e, em seguida, difere esses tokens, de modo que apenas as palavras alteradas são coloridas em vez de linhas inteiras.

git diff --color-words
diff --git a/test.txt b/test.txt
index 6b0c6cf..b37e70a 100644
--- a/test.txt
+++ b/test.txt
@@ -1 +1 @@
-this is a git diff test example
+this is a diff example

(Nota: --color-words destaca alterações inline usando cores de terminal. Em texto simples, o formato de saída corresponde ao diff padrão.)

git diff-highlight

Quando você clona o código-fonte do Git, um subdiretório chamado contrib vem junto. Ele contém ferramentas relacionadas ao Git, uma das quais é o diff-highlight. Ele destaca partes alteradas abaixo do nível de palavras, indo além do --color-words em granularidade. Note que esta ferramenta filtra a entrada padrão (você passa um diff por pipe para ela) e requer coloração de terminal para ser visível.

git diff | git diff-highlight
diff --git a/test.txt b/test.txt
index 6b0c6cf..b37e70a 100644
--- a/test.txt
+++ b/test.txt
@@ -1 +1 @@
-this is a git diff test example
+this is a diff example

Diff em ficheiros binários

O git diff pode ser executado não apenas em ficheiros de texto, mas também em binários. Por padrão, o resultado não é muito útil — o Git apenas diz que o ficheiro mudou, não como:

git diff
# Binary files a/script.pdf and b/script.pdf differ

O Git tem um recurso que permite especificar um comando shell para converter o conteúdo do ficheiro binário em texto antes de realizar o diff. É necessária uma pequena configuração. Primeiro, defina um filtro textconv que descreva como converter um determinado tipo binário em texto. Por exemplo, o utilitário pdftohtml (disponível pelo Homebrew) pode transformar um PDF em HTML. Há dois lugares para configurar isso: por repositório em .git/config, ou globalmente em ~/.gitconfig.

[diff "pdfconv"]
textconv=pdftohtml -stdout

Em seguida, conecte um ou mais padrões de ficheiros ao filtro pdfconv criando um ficheiro .gitattributes na raiz do repositório:

*.pdf diff=pdfconv

Após esta configuração, o git diff primeiro passa cada ficheiro binário correspondente pelo conversor e difere a saída de texto do conversor. Usando a mesma técnica, você pode obter diffs legíveis de muitos formatos binários (zips, jars e outros arquivos).

Comparando um único ficheiro

O git diff também aceita um caminho de ficheiro explícito. Quando um caminho é passado, a operação fica limitada a esse ficheiro. No exemplo abaixo, o argumento ./path/to/file compara as modificações no diretório de trabalho com o commit HEAD:

git diff HEAD ./path/to/file

Comparando todas as alterações

Para comparar as alterações em todo o repositório, execute git diff sem um caminho de ficheiro. Qualquer uma das formas acima pode ser invocada sem o argumento ./path/to/file para aplicar a mesma comparação em todos os ficheiros do repositório local.

Alterações desde o commit mais recente

Um git diff simples compara o diretório de trabalho com a área de staging (índice), portanto mostra apenas edições não staged. Para ver todas as alterações não confirmadas desde o commit mais recente — tanto staged quanto não staged — compare com HEAD:

git diff HEAD

Comparando dois commits

O git diff aceita refs do Git, como nomes de branches, tags e hashes de commit. Cada commit tem um ID único, que você pode encontrar com git log. Passe dois IDs de commit para compará-los diretamente:

git diff <commit-hash-1> <commit-hash-2>

A saída mostra o que mudou do primeiro commit para o segundo.

Comparando branches

Comparar branches funciona como qualquer outra entrada de ref para o git diff. Há dois operadores a conhecer.

O operador de dois pontos compara as pontas de ambos os branches:

git diff branch1..branch2

Você obtém o mesmo resultado se os pontos forem omitidos e um espaço for usado entre os nomes dos branches. Há também um operador de três pontos:

git diff branch1...branch2

O operador de três pontos rebase a comparação no histórico compartilhado: ele substitui branch1 pelo ancestral comum (merge base) dos dois branches, enquanto a segunda entrada permanece a ponta de branch2. Em outras palavras, branch1...branch2 responde "o que aconteceu em branch2 desde que ele divergiu de branch1", que é geralmente o que você quer ao revisar um branch de funcionalidade antes de um git merge.

Comparando um ficheiro entre dois branches

Para comparar um ficheiro específico entre branches, passe o caminho do ficheiro como terceiro argumento:

git diff master new_branch ./test.txt

Comandos relacionados

  • git status — veja quais ficheiros foram alterados antes de usar git diff para ver o que mudou neles.
  • git add — quando um diff parecer correto, faça o stage; depois use git diff --staged para revisar o que está staged.
  • git commit — registar as alterações staged.
  • git log — encontrar os hashes de commit que você passa para git diff <commit> <commit>.
  • git show — ver o diff introduzido por um único commit.

Prática

Prática
Quais são as funcionalidades e opções do comando 'git diff'?
Quais são as funcionalidades e opções do comando 'git diff'?
Was this page helpful?