Basico de diff e patch - Gerando e Aplicando Diferencas
O Que Voce Vai Aprender
- Como comparar dois arquivos com
diffe interpretar a saida - Como interpretar o formato unified diff (
diff -u) - Como aplicar um arquivo de patch com
patch - Como reverter um patch com
patch -R
Resumo Rapido
- Ver diff:
diff -u arquivo_antigo arquivo_novo - Salvar patch:
diff -u arquivo_antigo arquivo_novo > changes.patch - Aplicar patch:
patch -p0 < changes.patch - Reverter patch:
patch -R -p0 < changes.patch
Pre-requisitos
- SO: Ubuntu ou qualquer distribuicao Linux
diffepatchja vem instalados por padrao na maioria dos sistemas Linux
O Que e o diff?
diff compara dois arquivos linha por linha e mostra o que mudou entre eles. E usado diariamente para revisar alteracoes em codigo-fonte, comparar arquivos de configuracao com backups e gerar arquivos de patch para distribuicao.
Como Usar o diff
Comparacao Basica
$ diff old.txt new.txt
Se nao houver diferencas, nada e impresso. Quando ha diferencas, a saida no formato "normal" padrao se parece com isto:
2c2 < conteudo antigo --- > conteudo novo
O formato normal e dificil de ler e nao e adequado para o patch. Use o formato unificado em vez disso.
Formato Unificado (-u)
A opcao -u produz saida em formato unificado, o formato padrao para arquivos de patch.
$ diff -u old.txt new.txt
Exemplo de saida:
--- old.txt 2026-06-01 10:00:00.000000000 +0000
+++ new.txt 2026-06-01 10:05:00.000000000 +0000
@@ -1,5 +1,5 @@
line1 (unchanged)
-old line2
+new line2
line3 (unchanged)
Como interpretar:
| Simbolo | Significado |
|---|---|
--- |
Arquivo original (antes) |
+++ |
Arquivo modificado (depois) |
@@ |
Cabecalho do hunk com numeros de linha |
- |
Linha removida |
+ |
Linha adicionada |
(espaco) |
Linha de contexto (sem alteracao) |
O cabecalho do hunk @@ -1,5 +1,5 @@ significa: comecando na linha 1, mostrando 5 linhas do arquivo antigo / 5 linhas do arquivo novo. Tres linhas de contexto antes e depois de cada alteracao sao incluidas por padrao.
Comparacao Recursiva de Diretorios (-r)
Use -r com -u para comparar arvores de diretorios inteiras:
$ diff -ur dir_old/ dir_new/
Cada arquivo alterado aparece como um bloco unified diff separado na saida.
Opcoes Uteis do diff
| Opcao | Descricao |
|---|---|
-u |
Formato unificado (necessario para patch) |
-r |
Recursivo (comparar diretorios) |
-i |
Ignorar diferencas de maiusculas/minusculas |
-w |
Ignorar todos os espacos em branco |
-b |
Ignorar alteracoes na quantidade de espacos |
--color |
Colorir a saida (GNU diff) |
Salvando o Diff em um Arquivo de Patch
Redirecione a saida do diff para um arquivo:
# Arquivo unico $ diff -u original.txt modified.txt > changes.patch # Diretorio inteiro $ diff -ur dir_old/ dir_new/ > project.patch
Este arquivo e o que voce passa para o patch ao aplicar as alteracoes.
O Que e o patch?
patch recebe um arquivo diff produzido pelo diff e aplica essas alteracoes a um arquivo ou diretorio alvo. E assim que correcoes de bugs e patches de seguranca sao distribuidos em software de codigo aberto: o mantenedor executa diff, envia o arquivo .patch, e os usuarios executam patch para aplica-lo.
Como Usar o patch
Entendendo o Nivel de Remocao -p
A opcao -p controla quantos componentes iniciais do caminho devem ser removidos dos nomes de arquivos dentro do cabecalho do patch.
--- a/src/config.txt ← com -p1, interpretado como "src/config.txt"
+++ b/src/config.txt
| Opcao | Comportamento |
|---|---|
-p0 |
Usar o caminho completo como esta |
-p1 |
Remover um componente inicial (remove a/ ou b/) |
Patches gerados pelo Git sempre incluem os prefixos a/ e b/, entao -p1 e a escolha mais comum para patches do Git. Para patches criados com diff -u simples (sem prefixo), use -p0.
Dry Run Primeiro
Sempre faca uma previa antes de aplicar:
$ patch --dry-run -p0 < changes.patch
--dry-run verifica se o patch pode ser aplicado sem problemas sem modificar nenhum arquivo. Se nao reportar erros, prossiga com a aplicacao real.
Aplicando um Patch
Para patches criados com diff -u (simples, sem prefixo a//b/):
$ patch -p0 < changes.patch
Para patches gerados pelo Git ou patches com prefixos a//b/:
$ patch -p1 < project.patch
Se o patch reportar "Hunk FAILED", o patch nao corresponde ao estado atual do arquivo alvo. O arquivo pode ja ter sido patcheado ou foi modificado independentemente. Use --dry-run para diagnosticar antes de tentar.
Rejeicao de Hunks
Quando um hunk falha, o patch grava as partes rejeitadas em um arquivo .rej (ex.: config.txt.rej). Inspecione-o para aplicar as alteracoes manualmente.
Revertendo um Patch
A flag -R reverte um patch, aplicando-o desfaz a alteracao original:
$ patch -R -p0 < changes.patch # Patch em formato Git $ patch -R -p1 < project.patch
Reverter requer que as linhas de contexto no patch ainda correspondam ao arquivo alvo. Se o arquivo foi alterado apos o patch ter sido aplicado, a reversao pode falhar ou produzir resultados incorretos.
Fluxos de Trabalho Praticos
Compartilhando uma Alteracao em Arquivo de Configuracao
# 1. Salvar o original $ cp nginx.conf nginx.conf.orig # 2. Editar o arquivo $ vim nginx.conf # 3. Gerar o patch $ diff -u nginx.conf.orig nginx.conf > nginx-fix.patch # 4. Destinatario aplica o patch $ patch --dry-run -p0 < nginx-fix.patch $ patch -p0 < nginx-fix.patch
Aplicando um Patch de Codigo Aberto
# Executar a partir do diretorio raiz do projeto $ patch --dry-run -p1 < bugfix.patch $ patch -p1 < bugfix.patch # Desfazer se algo der errado $ patch -R -p1 < bugfix.patch
Gerando um Patch Compativel com Git
Ao trabalhar em um repositorio Git, git diff produz uma saida que o patch -p1 pode consumir diretamente:
$ git diff > my-changes.patch $ patch -p1 < my-changes.patch
Para alteracoes ja commitadas, git format-patch e mais apropriado pois preserva os metadados do commit.
Resumo
| Comando | Proposito |
|---|---|
diff -u old new |
Mostrar diff unificado |
diff -ur dir1/ dir2/ |
Comparar diretorios recursivamente |
diff -u old new > fix.patch |
Gerar um arquivo de patch |
patch --dry-run -p0 < fix.patch |
Previa da aplicacao do patch |
patch -p0 < fix.patch |
Aplicar patch (formato simples) |
patch -p1 < fix.patch |
Aplicar patch (formato Git) |
patch -R -p0 < fix.patch |
Reverter um patch |
Modelos para Copiar e Colar
# Gerar patch diff -u original.txt modified.txt > changes.patch # Previa patch --dry-run -p0 < changes.patch # Aplicar patch -p0 < changes.patch # Reverter patch -R -p0 < changes.patch