Boa parte dos casos em que dois arquivos "têm o mesmo conteúdo" e mesmo assim o diff mostra um monte de diferenças se deve a espaços: o editor apagou espaços no fim das linhas, trocou tabulações por espaços ou mudou a largura da indentação. As ferramentas de diff oferecem opções para ignorar essas diferenças, mas cada opção ignora um conjunto diferente de coisas, e é preciso saber exatamente o que cada uma faz.
Opções de espaço do GNU diff
| Opção | Nome longo | O que ignora |
|---|---|---|
-Z | --ignore-trailing-space | Espaços no fim da linha |
-E | --ignore-tab-expansion | Diferenças entre tabulações e os espaços em que elas se expandem |
-b | --ignore-space-change | Mudanças na quantidade de espaços e espaços no fim da linha |
-w | --ignore-all-space | Todos os espaços |
-B | --ignore-blank-lines | Mudanças que só adicionam ou removem linhas em branco |
-i | --ignore-case | Maiúsculas/minúsculas |
--strip-trailing-cr | O caractere CR no fim das linhas de entrada |
Opções equivalentes do git diff
A documentação do git as descreve assim:
--ignore-cr-at-eol: ignora o retorno de carro (CR) no fim da linha ao comparar.--ignore-space-at-eol: ignora mudanças de espaço no fim da linha.-b,--ignore-space-change: ignora mudanças na quantidade de espaços. Ignora espaços no fim da linha e considera equivalentes todas as sequências de um ou mais espaços.-w,--ignore-all-space: ignora espaços ao comparar linhas. Ignora a diferença mesmo quando uma linha tem espaço e a outra não.--ignore-blank-lines: ignora mudanças em que todas as linhas estão em branco.
A diferença decisiva entre -b e -w
É comum confundir as duas opções. O ponto central é se elas distinguem entre ter ou não ter espaço.
| Esquerda | Direita | -b (ignora quantidade) | -w (ignora todos) |
|---|---|---|---|
a b | a b | Igual | Igual |
a b | ab | Diferente | Igual |
x = 1 | x=1 | Diferente | Igual |
if (a) + espaço no fim | if (a) | Igual | Igual |
| Indentação com 1 tabulação | Indentação com 4 espaços | Igual | Igual |
O -b reduz cada sequência de espaços a um só espaço antes de comparar; o -w apaga todos os espaços. Por isso o -w considera iguais x = 1 e x=1, e até int a e inta.
O risco quando a indentação tem significado
Em arquivos em que a indentação faz parte da sintaxe, como Python, YAML e Makefile, as opções de ignorar espaços podem esconder mudanças reais.
if ready:
start()
notify()
if ready:
start()
notify()
No segundo, notify() saiu do bloco if e o comportamento mudou, mas comparando com -w todos os espaços são apagados e a diferença some. O -b detecta a diferença, porque o espaço no início da linha passou de "existe" para "não existe". Já quando a indentação muda de 4 para 8 espaços e o código entra em um bloco mais interno, só a quantidade de espaços mudou, e o -b também não mostra nada.
O método seguro é comparar arquivos em que a indentação importa com as opções de espaço desativadas. Use as opções de espaço para "confirmar que a mudança é só de formatação" e faça a verificação final sem opções — é um hábito mais seguro.
O alcance de ignorar linhas em branco (-B)
O -B e o --ignore-blank-lines do git ocultam mudanças compostas apenas de linhas em branco. Se a inclusão de uma linha em branco estiver no mesmo hunk que outra mudança real, essa linha em branco ainda pode aparecer. É útil para documentos em que mudou o número de linhas em branco entre parágrafos, ou quando um formatador de código ajustou as linhas em branco entre funções.
As opções deste site e seus equivalentes
| Este site | GNU diff mais próximo | git diff mais próximo |
|---|---|---|
| Espaços: comparar como está | (sem opção) | (sem opção) |
| Espaços: ignorar espaços no fim da linha | -Z | --ignore-space-at-eol |
| Espaços: ignorar quantidade de espaços | -b | -b |
| Espaços: ignorar todos os espaços | -w | -w |
| Ignorar maiúsculas/minúsculas | -i | (não se aplica) |
| Ignorar linhas em branco | Semelhante a -B (exclui as linhas em branco da comparação) | Semelhante a --ignore-blank-lines |
| Normalizar fim de linha | --strip-trailing-cr + ignorar a quebra de linha final | Semelhante a --ignore-cr-at-eol |
A opção "ignorar linhas em branco" deste site tira as linhas em branco da comparação por completo e só as mostra em cor apagada. Além disso, as opções de ignorar também valem para o destaque dentro da linha: com "ignorar quantidade de espaços" ativada, trechos que diferem só no número de espaços não são destacados.
Experimente nesta ferramenta
Cole os exemplos da tabela acima no comparador de textos e troque as opções de espaço uma a uma para ver a diferença na hora. As "diferenças invisíveis", como o CR no fim da linha ou a quebra de linha no fim do arquivo, estão em Caracteres de fim de linha e diferenças invisíveis, e a forma de ler o resultado como patch está em Como ler um unified diff.