Por que usar diff / patch quando é mais fácil usar apenas cp

19
diff -u file1.txt file2.txt > patchfile

cria um arquivo de patch que consiste em instruções para patchconverter file1.txt para ser exatamente como file2.txt

Isso não pode ser feito usando o cpcomando? Eu posso imaginar que isso seja útil para quando o arquivo for muito grande e precisar ser transferido por uma rede em que essa abordagem possa economizar largura de banda. Existe alguma outra maneira de usar o diff / patch que seria vantajoso em outros cenários?

toddlermenot
fonte

Respostas:

31

As diferenças podem ser mais complicadas do que apenas comparar um arquivo com outro. O pode comparar hierarquias de diretórios inteiras. Considere o exemplo que quero corrigir um bug no GCC. Minha alteração adiciona uma ou duas linhas em 4 ou 5 arquivos e exclui algumas linhas nesses e em outros arquivos. Se eu quiser comunicar essas alterações a alguém, potencialmente para inclusão no GCC, minhas opções são

  • Copie toda a árvore de origem
  • Copie apenas os arquivos que foram alterados
  • Forneça apenas as alterações que fiz

Copiar toda a árvore de origem não faz sentido, mas e as outras duas opções, que estão no centro da sua pergunta. Agora considere que outra pessoa também trabalhou no mesmo arquivo que eu e nós dois damos nossas alterações a alguém. Como essa pessoa saberá o que fizemos e se as alterações são compatíveis (diferentes partes do arquivo) ou conflitam (mesmas linhas do arquivo)? Ele irá diferenciá-los! O diff pode dizer a ele como os arquivos diferem entre si e do arquivo de origem não modificado. Se o diff é o necessário, faz mais sentido enviar o diff em primeiro lugar. Um diff também pode conter alterações em mais de um arquivo; portanto, enquanto editei 9 arquivos no total, posso fornecer um único arquivo diff para descrever essas alterações.

As diferenças também podem ser usadas para fornecer história. E se uma mudança de três meses atrás causasse um bug que eu descobri hoje? Se eu puder restringir quando o bug foi introduzido e isolá-lo para uma alteração específica, posso usar o diff para "desfazer" ou reverter a alteração. Isso não é algo que eu poderia fazer tão facilmente se estivesse apenas copiando arquivos.

Isso tudo se vincula ao controle de versão de origem, onde os programas podem registrar o histórico de arquivos como uma série de diferenças desde o momento em que foi criado até hoje. Os diffs fornecem histórico (eu posso recriar o arquivo como era em qualquer dia em particular), posso ver quem culpar por quebrar algo (o diff tem um proprietário) e posso enviar facilmente alterações para projetos upstream, fornecendo-lhes diffs específicos ( talvez eles só estejam interessados ​​em uma mudança quando eu fiz muitas).

Em resumo, sim, cpé mais fácil diffe patch, mas a utilidade diffe patché maior que cppara situações em que é importante rastrear como os arquivos são alterados.

Casey
fonte
De fato, o git realmente não armazena o histórico do arquivo como diferenças nas confirmações subsequentes. Para cada confirmação é armazenada, o conteúdo de cada arquivo (consulte "git show -s --pretty = raw" e "git ls-tree HEAD"). Em seguida, na parte superior dessa camada, como muitos arquivos serão semelhantes em confirmações diferentes, ele usa a compactação delta para compartilhar dados entre arquivos (mas isso não está vinculado ao histórico).
ysdx 7/09/2015
As diferenças, no entanto, são uma ferramenta de visualização conveniente para essa história.
ysdx 7/09/2015
20

Quando você obtém um patch, é possível frequentemente (ou seja, a menos que você tenha feito alterações nas mesmas linhas) aplicar o patch a um conjunto de arquivos que você também alterou.

O patch contém informações sobre o antigo e o novo estado dos arquivos. Se você obtém um arquivo copiado, não sabe qual era o original (o estado antigo) e não pode aplicar as diferenças a um arquivo (ou conjunto de arquivos) que você alterou sem grande dificuldade. Portanto, para conjuntos de arquivos de origem, não é a preservação de espaço que é uma grande preocupação, são as informações antes e depois.

Antes das diferenças (de contexto / unificadas), isso costumava ser feito com instruções para editores (inserir uma linha após X, excluir linha Y), mas isso só funcionaria se você soubesse o estado em que essas instruções começaram. Assim, tendo o mesmo problema que a sua "solução" com apenas copiar.

Anthon
fonte
2
um arquivos de patch também permite que você desfazê-lo e aplicá-lo em vários arquivos de uma só vez
Gilsham
Na verdade, diffs ( diff -u) unificados são uma melhoria projetada para seres humanos, eles não ajudam a robustez contra conflitos sobre diferenças de contexto regulares ( diff -c), eu acho. Mesmo diffs simples ( diff) ainda funcionam frequentemente sem saber exatamente o "estado em que essas instruções começaram". No entanto, isso é melhor do que a resposta aceita, porque falar sobre como os arquivos de correção podem corrigir vários arquivos de origem ao mesmo tempo é realmente um problema.
Celada
@celeda, você está certo sobre as diferenças de contexto, entre isso e diferenças normais é onde está a principal distinção. Sem o contexto, as correções são muito mais difíceis de aplicar ao contrário, se é que o fazem.
Anthon
12

Se você estiver usando diff, poderá ver exatamente o que mudou; portanto, usar diff / patch é uma maneira de impedir que alguém introduza alterações indesejadas no arquivo.

Thomas Weinbrenner
fonte
11

As alterações feitas nos arquivos geralmente são muito menores que os arquivos que estão sendo alterados.

Isso significa que armazenar um diff pode economizar muito espaço. Quando difffoi criado, o espaço em disco era caro.

Mas isso também significa que você pode aplicar novamente um diff a um arquivo, mesmo quando esse arquivo foi alterado de outras maneiras. O utilitário de correção fará isso por você e informará quando houver problemas.

Este é, de fato, o motivo mais importante para trabalhar com diferenças no desenvolvimento de software. Quando uma alteração é feita (geralmente em mais de um arquivo), ela pode ser salva como um diff: o resultado é chamado de conjunto de alterações ou patch . Se tudo estiver bem, o patch não é apenas uma mudança arbitrária, mas implementa algum tipo de mudança funcional - por exemplo, uma correção de bug ou um novo recurso.

Enquanto isso, uma mudança diferente pode ser feita, possivelmente por um desenvolvedor diferente, mesmo em um local diferente. Se as alterações não foram feitas nas mesmas partes dos mesmos arquivos, elas podem ser aplicadas independentemente. Assim, os desenvolvedores podem enviar seus patches para testes. Um conjunto inteiro de patches pode ser construído, representando possíveis alterações; alguns deles podem ser rejeitados, o restante será integrado ao sistema.

Portanto, trabalhar com diffs permite o desenvolvimento simultâneo. Você não precisa mais trabalhar em uma alteração de cada vez.

Os modernos sistemas de controle de versão distribuída são uma continuação dessa maneira de trabalhar.

reinierpost
fonte
1

Em suma, pode. Se você assiste a alguns vídeos do Thinkg Big Larry Wall no youtube, ele fala sobre como o diff / patch foi iniciado e quais problemas eles resolveram. Em essência, tratava-se de reduzir o tamanho da comunicação pela Internet, mantendo os patches flexíveis e legíveis por humanos. .

Se você está em um sistema local e não se importa com nenhuma dessas coisas, então cpou rsyncestá bem.

PSkocik
fonte
Obrigado PSKocik. Você poderia compartilhar o link para esse vídeo?
Toddlermenot # 8/15
Discordo da última afirmação. Hoje em dia, não se trata de tamanho, trata-se de acompanhar seu processo de desenvolvimento, para que fique mais fácil de gerenciar.
Reinierpost
@reinierpost use git para rastrear meu processo de desenvolvimento. Eu não faço o patch diretamente.
PSKocik