Ferramentas do usuário

Ferramentas do site


dev:funcionamento_patch_diff

patch e diff

Este post e sobre um assunto que costumo muito esquecer, sendo assim colocarei aqui exemplos rápidos para não esquecer :) .

Verificando as diferenças

Vamos começar entendendo o comando diff, e o que ele faz. Resumidamente ele processa as diferenças entre dois arquivos vamos a um exemplo bem simples.

ricardobarbosa@isadora:~/patch$ cat texto01.txt 
ola mundo!
ricardobarbosa@isadora:~/patch$ 
ricardobarbosa@isadora:~/patch$ 
ricardobarbosa@isadora:~/patch$ cat texto02.txt 
teste
ricardobarbosa@isadora:~/patch$

Vamos ver a diferença dos arquivos

ricardobarbosa@isadora:~/patch$ diff texto01.txt texto02.txt 
1c1
< ola mundo!
---
> teste
ricardobarbosa@isadora:~/patch$

Vamos analisar a saída do comando:

  • “1c1” ← o primeiro número é a linha, no caso a linha 1, do arquivo texto01.txt que deve ser modificada e a letra “c” é de change, alterar pela linha 1 do arquiv texto02.txt.
  • “<” ola mundo! ← o símbolo “<” indica a linha deve ser removida.
  • “- - -” ← aqui separa da informação a ser substituída.
  • “>” teste ← o símbolo “>” indica que deve ser incluída a informação.

As ações disponivéis:

  • a - adiciona o conteúdo da linha.
  • c - substitui o conteúdo da linha de um arquivo pelo do outro arquivo.
  • d - deleta o conteúdo da linha evidenciada.

Criar um arquivo de remendo (patch)

É possivel com o comando patch criar um remendo ou uma atualização no exemplo anterior podemos deixar o arquivo texto01.txt igual ao texto02.txt ou vice-versa. Para isso precisamos de um arquivo com as alterações a serem realizadas esse arquivo recebe o nome de patch. Para criar um arquivo de patch no exemplo anterior utilizamos o seguinte comando.

ricardobarbosa@isadora:~/patch$ diff texto01.txt texto02.txt > patch01
ricardobarbosa@isadora:~/patch$ 
ricardobarbosa@isadora:~/patch$ patch texto01.txt patch01
patching file texto01.txt
ricardobarbosa@isadora:~/patch$ cat texto01.txt 
teste
ricardobarbosa@isadora:~/patch$

Vamos entender o que aconteceu:

  1. Primeiro geramos o arquivo de patch com o nome patch01 diff texto01.txt texto02.txt > patch01
  2. Depois aplicamos o patch patch texto01.txt patch01, ou seja transformamos o arquivo texto01.txt igual ao arquivo texto02.txt
  3. Verificamos isso com o comando cat texto01.txt.

Outra opção interessante da dupla diff+patch e a possibilidade de reverter o patch mas para isso precisamos criar o arquivo de patch com a opção -u.

ricardobarbosa@isadora:~/patch$ diff texto01.txt texto02.txt
1c1
< ola mundo!
---
> teste
ricardobarbosa@isadora:~/patch$ diff -u texto01.txt texto02.txt
--- texto01.txt 2018-11-01 18:41:03.415117565 -0300
+++ texto02.txt 2018-11-01 16:48:54.727238063 -0300
@@ -1 +1 @@
-ola mundo!
+teste
ricardobarbosa@isadora:~/patch$ diff -u texto01.txt texto02.txt > patch01 
ricardobarbosa@isadora:~/patch$ patch texto01.txt patch01
patching file texto01.txt
ricardobarbosa@isadora:~/patch$ cat texto01.txt 
teste
ricardobarbosa@isadora:~/patch$ patch -R < patch01
patching file texto01.txt
ricardobarbosa@isadora:~/patch$ cat texto01.txt 
ola mundo!
ricardobarbosa@isadora:~/patch$ 

repare que nesta sequencia de comandos temos o arquivo de patch criado sem a opção -u e com a opção, a diferença principal que com -u ele exibe as informações de arquivos a serem patcheados, isso para quando quiser reverter saber quais arquivos mudar. Repare que gerei o patch com -u depois executei o patch visualizei o arquivo patcheado, e depois fiz a reversão e visualizei o mesmo arquivo novamente, espero que tenha ficado claro :) .

Patcheando arquivo de verdade :)

Agora vamos para algo mais usual vamos baixar duas versões fonte do apache para criar um patch e aplicar deixar uma versão igualmente a outra, ou seja, atualizar o apache de versão inferior.

versões que utilizei

Vamos descompactar os dois arquivos.

ricardobarbosa@isadora:~/patch$ tar -jxvf httpd-2.4.32.tar.bz2 
httpd-2.4.32/
httpd-2.4.32/config.layout
httpd-2.4.32/configure.in
httpd-2.4.32/Makefile.win
httpd-2.4.32/configure
httpd-2.4.32/test/
httpd-2.4.32/test/test_parser.c
httpd-2.4.32/test/check_chunked
httpd-2.4.32/test/make_sni.sh
httpd-2.4.32/test/README
httpd-2.4.32/test/test-writev.c
httpd-2.4.32/test/test_limits.c
httpd-2.4.32/test/tcpdumpscii.txt
httpd-2.4.32/test/test_find.c
.......
httpd-2.4.32/docs/manual/new_features_2_2.html.tr.utf8
httpd-2.4.32/docs/manual/stopping.html.es
httpd-2.4.32/docs/manual/new_features_2_0.html
httpd-2.4.32/docs/manual/urlmapping.html
httpd-2.4.32/buildconf
httpd-2.4.32/Makefile.in
httpd-2.4.32/srclib/
httpd-2.4.32/srclib/Makefile.in
ricardobarbosa@isadora:~/patch$ 
ricardobarbosa@isadora:~/patch$ tar -jxvf httpd-2.4.37.tar.bz2 
httpd-2.4.37/
httpd-2.4.37/config.layout
httpd-2.4.37/configure.in
httpd-2.4.37/Makefile.win
httpd-2.4.37/configure
httpd-2.4.37/test/
httpd-2.4.37/test/test_parser.c
httpd-2.4.37/test/check_chunked
httpd-2.4.37/test/make_sni.sh
httpd-2.4.37/test/README
httpd-2.4.37/test/test-writev.c
httpd-2.4.37/test/test_limits.c
httpd-2.4.37/test/tcpdumpscii.txt
httpd-2.4.37/test/test_find.c
httpd-2.4.37/test/.indent.pro
httpd-2.4.37/test/test_select.c
.....
httpd-2.4.37/docs/manual/glossary.html.fr.utf8
httpd-2.4.37/docs/manual/caching.html
httpd-2.4.37/docs/manual/custom-error.html.ja.utf8
httpd-2.4.37/docs/manual/new_features_2_2.html.tr.utf8
httpd-2.4.37/docs/manual/stopping.html.es
httpd-2.4.37/docs/manual/new_features_2_0.html.fr.utf8
httpd-2.4.37/docs/manual/new_features_2_0.html
httpd-2.4.37/docs/manual/urlmapping.html
httpd-2.4.37/buildconf
httpd-2.4.37/Makefile.in
httpd-2.4.37/srclib/
httpd-2.4.37/srclib/Makefile.in
ricardobarbosa@isadora:~/patch$

Agora vamos criar o arquivo de patch

ricardobarbosa@isadora:~/patch$ diff -Naur /home/ricardobarbosa/patch/httpd-2.4.32/ /home/ricardobarbosa/patch/httpd-2.4.37 > apache.patch
ricardobarbosa@isadora:~/patch$

Vamos aplicar o patch

ricardobarbosa@isadora:~/patch/httpd-2.4.32$ patch -p5 < ../apache.patch
patching file build/config.guess
patching file build/config.sub
patching file build/installwinconf.awk
patching file CHANGES
patching file CMakeLists.txt
patching file config.layout
patching file configure
patching file configure.in
patching file docs/error/contact.html.var
patching file docs/error/HTTP_BAD_GATEWAY.html.var
patching file docs/error/HTTP_BAD_REQUEST.html.var
patching file docs/error/HTTP_FORBIDDEN.html.var
patching file docs/error/HTTP_GONE.html.var
patching file docs/error/HTTP_INTERNAL_SERVER_ERROR.html.var
patching file docs/error/HTTP_LENGTH_REQUIRED.html.var
patching file docs/error/HTTP_METHOD_NOT_ALLOWED.html.var
patching file docs/error/HTTP_NOT_FOUND.html.var
patching file docs/error/HTTP_NOT_IMPLEMENTED.html.var
......
patching file server/util_script.c
patching file server/vhost.c
patching file support/ab.c
patching file support/htpasswd.c
patching file support/passwd_common.c
patching file support/passwd_common.h
patching file support/rotatelogs.c
patching file support/suexec.c
patching file support/win32/ApacheMonitor.c
ricardobarbosa@isadora:~/patch/httpd-2.4.32$ 

Se você olhar no tamanho dos arquivos estão com o mesmo tamanho.

ricardobarbosa@isadora:~/patch$ du -h httpd-2.4.37
....
8,0K    httpd-2.4.37/srclib
88K     httpd-2.4.37/test
46M     httpd-2.4.37
ricardobarbosa@isadora:~/patch$
ricardobarbosa@isadora:~/patch$ du -h httpd-2.4.32
....
696K    httpd-2.4.32/build
8,0K    httpd-2.4.32/srclib
88K     httpd-2.4.32/test
46M     httpd-2.4.32
ricardobarbosa@isadora:~/patch$

O diretorio dos fontes sem aplicação de patch possue 45M

ricardobarbosa@isadora:~/patch$ du -h httpd-2.4.32
....
696K    httpd-2.4.32/build
8,0K    httpd-2.4.32/srclib
88K     httpd-2.4.32/test
45M     httpd-2.4.32
ricardobarbosa@isadora:~/patch$ 

Bom fica a dica e estou aberto as criticas