O que é um patch no controle de versão do git?

136

Eu sou novo no git e no controle de versão, então estou tentando descobrir o que é um patch e como ele é diferente do restante das atividades que faço no git?

Quando aplico um patch? Isso acontece toda vez que eu comprometo?

Amit Erandole
fonte

Respostas:

116

Você pode ver nesta postagem no blog como criar um patch (coleção de alterações que deseja comunicar e aplicar a outro repo)

patch git
(foto da postagem de blog de 2008 " Bioruby with git: como isso funcionaria? ", publicada por Jan AERTS )

Veja também Contribuindo para o Rails com Git como outro exemplo concreto.

Atualmente, a solicitação de recebimento do GitHub facilita a aplicação de patches nos repositórios do GitHub, o que é útil quando você não é um colaborador direto (ou seja, você não tem o direito de enviar diretamente para um repositório).
Na verdade, recentemente, o GitHub introduziu " Better Pull Request Emails " para melhorar a notificação de novos patches.

VonC
fonte
4
Uma boa resposta e uma que me diz que um 'patch' do GIT não é o que estou procurando.
RonLugge
91

Patch é um programa Unix que atualiza arquivos de texto de acordo com as instruções contidas em um arquivo separado, chamado arquivo de patch.

Portanto, em outras palavras, pode significar o arquivo com instruções ou um programa que processa esse arquivo e o aplica a alguma coisa.

Agora, o que é um arquivo de correção? Digamos que você tenha um arquivo de texto com 2 linhas:

This is line A.
This is line B, or otherwise #2.

Então você altera a primeira linha e agora seu arquivo fica assim:

This is SPARTA.
This is line B, or otherwise #2.

Como você descreveria a alteração no conteúdo do arquivo? Você pode dizer que a primeira linha "Esta é a linha A." foi substituído por "This is SPARTA." ou até a última palavra "A" da primeira linha foi substituída por outra palavra "SPARTA". E é exatamente isso que o diff nos diz. Digamos que eu tenho duas versões deste arquivo, uma chamada file1.txt e outra file2.txt, então eu executo o diff e obtenho isso:

$ diff -u file1.txt file2.txt 
--- file1.txt   2011-11-26 11:07:03.131010360 -0500
+++ file2.txt   2011-11-26 11:07:13.171010362 -0500
@@ -1,2 +1,2 @@
-This is line A.
+This is SPARTA.
 This is line B, or otherwise #2.

Tendo uma descrição das alterações, você pode aplicá-lo a um conteúdo inicial e obter um conteúdo modificado. E essas mudanças, colocadas em formato unificado que os programas semelhantes a "patches" podem entender, são chamadas de arquivo de patches. É como, em vez de pegar um peixe de alguém que ele ensina como pescar, para que você possa cavá-lo nas águas. Agora, vamos aplicar nosso patch ao arquivo1.txt para torná-lo exatamente como o arquivo2.txt:

$ cat file1.txt 
This is line A.
This is line B, or otherwise #2.
$ cat file2.txt 
This is SPARTA.
This is line B, or otherwise #2.
$ diff -u file1.txt file2.txt > changes.patch
$ cat changes.patch 
--- file1.txt   2011-11-26 11:09:38.651010370 -0500
+++ file2.txt   2011-11-26 11:07:13.171010362 -0500
@@ -1,2 +1,2 @@
-This is line A.
+This is SPARTA.
 This is line B, or otherwise #2.
$ patch < changes.patch 
patching file file1.txt
$ cat file1.txt 
This is SPARTA.
This is line B, or otherwise #2.
$ 

Você pode pensar que é mais fácil ter apenas duas versões desse arquivo. Bem, neste caso simples, isso é verdade. Mas quando você tem muitos arquivos e esses arquivos são muito grandes, é muito mais eficiente ter algumas linhas de alterações em vez de duas cópias da coisa toda.

Quando falamos em termos de git, o arquivo de correção ainda significa a mesma coisa, mas usar o diff + patch você mesmo seria um pesadelo. Por exemplo, você sempre precisará ter duas versões do arquivo (ou mesmo todo o repositório) retiradas para compará-las. Não parece tão bom, não é? Portanto, o git cuida de todo o trabalho árduo para você - ele compara seu arquivo local com o que existe no repositório com o qual você está trabalhando e pode mostrá-lo como um "diff" ou aplicar esse "diff" como um o patch, também conhecido como, comprometa suas alterações ou até mesmo aplique algum arquivo de patch que você já possui. Sem aprofundar os detalhes, nesse sentido, o git é absolutamente o mesmo que outros sistemas de controle de versão como SVN, ou mesmo CVS ou forçosamente.

Espero que ajude!


fonte
Nunca soube que o git usa o patchprograma incorporado . Eu pensei que o git tivesse sua própria implementação.
Radianthaw
43

Um patch é um pequeno arquivo que indica as alterações feitas em um repositório. Geralmente é usado quando alguém de fora da sua equipe tem acesso somente leitura, mas teve uma boa alteração de código disponível. Ele então cria um patch e envia para você. Você o aplica e o envia ao repositório git. Todos se beneficiam da versão atualizada, e o autor do patch não precisa de acesso de leitura / gravação.

É realmente principalmente uma questão de segurança (pelo menos, é para isso que as pessoas a usam).

Tom van der Woerdt
fonte
1
Informações adicionais: Embora o git não use patches internamente, um objetivo do projeto é facilitar a troca de patches (porque muitos projetos funcionam dessa maneira, por exemplo, Linux e o próprio git). Portanto, o git possui comandos especiais para lidar com patches ( git diffmostra as alterações como patches por padrão, git applypermite aplicar um patch, etc.).
sleske
Parabéns! Você realmente acertou em cheio para que patches são usados, ou seja, um meio de enviar alterações aos repositórios aos quais o autor das alterações não tem acesso de gravação. Portanto, o modelo de solicitação de fork e pull do GitHub é um substituto para o modelo de patch de distribuição de alterações. Portanto, acredito que os patches são úteis apenas fora do contexto de ferramentas como o GitHub.
mljrg
8

Um arquivo de correção representa um único conjunto de alterações que podem ser aplicadas a qualquer ramificação, em qualquer ordem. Ao usar o patch, você obtém diferenças entre um ou mais arquivos. E mais tarde, você pode aplicar as diferenças (patch) para obter as alterações em novos arquivos. Existem muitos usos para um patch no Git. Se você tiver alterações não confirmadas no diretório de trabalho e precisar que essas alterações sejam aplicadas em outro lugar, basta criar um patch e aplicá-lo.

git diff > mypatch.patch

Se você tiver novos arquivos em seu repositório (não rastreado), deverá preparar o arquivo antes de criar um patch (não confirmar) e usar o seguinte comando

git diff --cached > mypatch.patch 

Posteriormente, você pode aplicar o patch:

git apply mypatch.patch

Se você quiser fazer algumas alterações em um repositório git, sem permissão de gravação, faça as alterações e crie um patch entre os dois, e envie o patch a alguém que tenha permissão para aplicar o patch. suas alterações devem ser adicionadas ao repositório git.

Anuraj
fonte
Melhores demonstrações: robots.thoughtbot.com/… . Meu resumo básico de exemplo: git format-patch <base_commit_or_branch_name>= agrupe todas as confirmações a partir de agora para <base_commit_or_branch_name> em arquivos legais e organizados que contêm as mensagens diff e as commit, para envio fácil (por exemplo, por email) para outra pessoa que queira corrigi-las. sua base de código. Em seguida, o destinatário corrige o seu sistema com o seu arquivo:cat *.patch | git am
Gabriel Staples
7

Um patch é um conjunto de diferenças entre um ou mais arquivos, para mostrar o que há de diferente entre eles. Você normalmente geraria apenas um patch para mostrar a alguém o que mudou. Um exemplo de quando você pode fazer isso é quando encontra e corrige um bug em um aplicativo de código aberto e depois publica a correção no rastreador de erros.

Steve Rukuts
fonte