Diferença Entre Arquivos & Patches

Introdução

O comando diff é utilizado para gerar diferenças entre dois arquivos. O seu uso é aconselhável para desenvolvedores de software porque permite visualizar ou enviar para um terceiro somente as partes modificadas e não um arquivo inteiro. Imagine em um projeto grande, que contenha arquivos de vários KBs o quanto essa ferramenta pode ser útil.

O comando patch é a ferramenta inversa do diff. Ele recebe um arquivo, geralmente de extensão .diff ou .patch, e aplica as correções indicadas.

Diff

Na prática o modo padrão que o diff gera não é usado, no seu lugar usa-se os modos unified (-u, --unified) ou context (-c). Neste documento usaremos o modo unified.

Diferença Entre Dois Arquivos

Primeiro o arquivo original chamado de hello.c
/*
 * hello.c
 */

main()
{
  printf("hello!\n");
}
Agora o arquivo já modificado, chamado de hello-novo.c
/*
 * hello.c
 */

#include <stdlib.h>

int main(int argc, char *argv[])
{
  printf("hello!\n");
  return 0;
}
Após a execução do comando diff -u hello.c hello-novo.c >hello.patch, este arquivo irá conter
--- hello.c	2003-11-24 19:10:16.000000000 -0200
+++ hello-novo.c	2003-11-24 19:48:32.000000000 -0200
@@ -2,7 +2,10 @@
  * hello.c
  */
 
-main()
+#include <stdlib.h>
+
+int main(int argc, char *argv[])
 {
   printf("hello!\n");
+  return 0;
 }
Vejamos agora o significado de cada uma dessas linhas

Diferença De Arquivos Entre Dois Diretórios

Para um conjunto maior de alterações não faz sentido gerar patch individuais, é mais fácil alterar os arquivos de uma árvore e no fim gerar um patch com todas as modificações reunidas. A sintaxe do comando diff torna-se então
diff -urN diretório_original diretório_modificado
Essas flags tem o seguinte significado:

Patch

O patch aceita um arquivo através da entrada padrão e o uso mais simples dele é executá-lo dentro de um diretório contendo arquivos fontes de uma versão prévia e aplicar o patch para obter uma versão alterada do fonte, possivelmente corrigindo algum bug ou simplesmente atualizando os fontes para uma versão mais nova, como em:
$ cd hello
$ patch <../hello-novo.patch

Resumo

Para criar um patch
$ tar zxvf hello-1.2.3.tar.gz
$ cp -r hello-1.2.3 hello-1.2.3.ORIG	# mantenho uma cópia original
$ cd hello-1.2.3
$ vim hello.c	# faço as minhas mudanças
$ cd ..
$ diff -Nur hello-1.2.3.ORIG hello-1.2.3 >hello-novo.patch

Para aplicar um patch

$ tar zxvf hello-1.2.3.tar.gz	# pego uma cópia da versão antiga
$ cd hello-1.2.3
$ patch <../hello-novo.patch	# ok, versão nova