git: patch não se aplica

289

Eu tenho um determinado patch chamado my_pcc_branch.patch.

Quando tento aplicá-lo, recebo a seguinte mensagem:

$ git apply --check my_pcc_branch.patch
warning: src/main/java/.../AbstractedPanel.java has type 100644, expected 100755
error: patch failed: src/main/java/.../AbstractedPanel.java:13
error: src/main/java/.../AbstractedPanel.java: patch does not apply

O que isso significa?

Como posso resolver este problema?

Dmitrii Pisarenko
fonte
Existem arquivos AbstractedPanel.java.rej por aí? Típico significa que um bot de linha foi alterado na fonte e no patch (aqui a linha 13 parece ser afetada).
Rudi
Não, não encontrei nenhum arquivo * .rej.
Dmitrii Pisarenko
Não sei por que a resposta aceita o corrigia (então, desconfio que seja um arenque vermelho), mas não has type 100644, expected 100755implica que haja uma incompatibilidade de permissões chmod em algum lugar?
Ruffin

Respostas:

325

git apply --reject --whitespace=fix mychanges.patch trabalhou para mim.

Explicação

A --rejectopção instruirá o git a não falhar se não puder determinar como aplicar um patch, mas para aplicar blocos individuais, ele poderá aplicar e criar arquivos de rejeição ( .rej) para blocos que não podem ser aplicados. O Wiggle pode "aplicar [esses] patches rejeitados e executar diferenças de palavras".

Além disso, --whitespace=fixavisará sobre erros de espaço em branco e tentará corrigi-los, em vez de recusar aplicar um pedaço aplicável.

As duas opções juntas tornam a aplicação de um patch mais robusta contra falhas, mas requerem atenção adicional em relação ao resultado.

Para toda a documentação, consulte https://git-scm.com/docs/git-apply .

user1028904
fonte
8
Isso realmente funcionou melhor para mim, porque não modificou completamente o meu arquivo
Wayne Werner
10
Isso é ótimo. Apenas rejeita o que ele não pode resolver sozinho e, em seguida, você pode apenas modificar os arquivos rejeitados manualmente.
Dennis
1
o patch -p1 <mychanges.patch # aplica alterações em partes. Se as alterações falharem, um patch <sourcefile> .orig e <sourcefile> .rej será criado e você poderá aplicar as alterações manualmente. Acho que o git apply --reject faz o mesmo e --whitespace = fix é magicamente melhor.
precisa saber é
7
esse comando cria .rejarquivos quando não é possível detectar automaticamente como aplicar um patch. Você pode usar o wiggle para resolver esses problemas.
precisa saber é o seguinte
14
Esta resposta não explica nada, em particular em quais casos ela funcionará. Gente, você realmente precisa ser mais exigente em termos de qualidade de resposta, isso não é um fórum.
Oliver
319

Johannes Sixt da lista de discussão [email protected] sugerido usando os seguintes argumentos da linha de comando:

git apply --ignore-space-change --ignore-whitespace mychanges.patch

Isso resolveu meu problema.

Dmitrii Pisarenko
fonte
25
Alguém pode me ajudar e explicar por que isso funciona? A outra resposta não funcionou para mim e eu tive exatamente o mesmo problema que o que o solicitante da pergunta descreve. O que os atributos de arquivo têm a ver com ignorar espaços em branco?
Skrebbel #
1
Usando o Windows PowerShell Um patch feito com o git diff foi aplicado com sucesso da seguinte maneira: git diff HEAD..613fee - myfile.xml | git aplicar --ignore-space-change --ignore-espaço em branco, enquanto primeiro salvar a saída diff como um arquivo não funcionou, no caso de alguém corre para o mesmo problema
TJB
2
tente -C1mudar para aplicar, reduz o contexto em torno de adições consideradas importantes.
Amir Ali Akbari
2
@ EricWalker, a magia git com CR / LF não é necessariamente uma coisa ruim. A alternativa pode ser que metade dos seus conjuntos de alterações consista em que cada linha em cada arquivo tocado seja alterada de uma linha para outra, com a alteração real oculta em algum lugar no meio.
GTC
3
Isso ajuda às vezes. Mas outras vezes, ainda recebo o "patch não se aplica", mesmo que o patch deva ser aplicado sem problemas.
Thomas Levesque
118

Quando tudo mais falhar, tente git applya --3wayopção .

git apply --3way patchFile.patch

--3way
Quando o patch não se aplica de maneira limpa, volte à mesclagem de três vias se o patch registrar a identidade dos blobs aos quais ele deve se aplicar e tivermos esses blobs disponíveis localmente, possivelmente deixando os marcadores de conflito nos arquivos em a árvore de trabalho para o usuário resolver. Esta opção implica a opção --index e é incompatível com as opções --reject e --cached.

O caso típico de falha aplica o máximo possível do patch e deixa você com conflitos para resolver o git, da maneira que normalmente o faz. Provavelmente um passo mais fácil que a rejectalternativa.

ruffin
fonte
2
Esta é a resposta que funcionou para mim. O arquivo que eu estava remendando não refletem as mudanças que eu gerados o patch a partir de (porque eu apaguei as alterações depois eu criei o patch.)
Christia
3
Boa solução geral. O diff de 3 vias não parecia normalmente normal, mas um pouco confuso com isso, mas mesmo assim isso me deu a capacidade de resolver o conflito e fazer com que o patch fosse aplicado.
steinybot
8
Eu acho que esse --3waydeve ser o comportamento padrão. Quando o patch falhar, pelo menos me diga o que falhou, para que eu possa corrigi-lo manualmente. git applyapenas falha e não informa por que algo falha. Eu não conseguia nem encontrar *.rejarquivos como os que hggera.
Pavan Manjunath
4
Definitivamente, a melhor solução. Deixe o usuário resolver seus próprios conflitos!
Mosh Feu
56

Este comando aplicará o patch que não está resolvendo, deixando arquivos inválidos como *.rej:

git apply --reject --whitespace=fix mypath.patch

Você apenas tem que resolvê-los. Uma vez resolvido, execute:

git -am resolved
Ivan Voroshilin
fonte
7
como resolver *.rej- tudo o que posso encontrar é fazer as alterações manualmente no arquivo de origem e excluir esses .rejarquivos. Qualquer outra maneira ?
coding_idiot
1
@coding_idiot Como de costume, Basta verificar os arquivos .rej, compará-los com os arquivos conflitantes e, finalmente, adicionar os arquivos fixos ao índice (com "FIXED_FILES add git")
Ivan Voroshilin
2
@coding_idiot você pode usar o wiggle para resolvê-lo. Por exemplo: wiggle --replace path/to/file path/to/file.rej. Este comando aplicará alterações de .rejarquivo para arquivo original. Também cria uma cópia do arquivo original, como path/to/file.porig. Por favor, a documentação de checkout para obter mais informações sobre a manobra
goodniceweb
22

Tente usar a solução sugerida aqui: https://www.drupal.org/node/1129120

patch -p1 < example.patch

Isso me ajudou.

Pini Cheyni
fonte
3
Eu sei que você não deveria fazer isso, mas MUITO OBRIGADO! Me salvou horas. Eu estava recebendo "patch não se aplica" e todos os tipos de erros.
Sudo rm -rf slash
@ sudorm-rfslash, por que não devemos fazer isso e por que você estava fazendo isso?
Preto
git: 'patch' is not a git command.emgit version 2.21.1 (Apple Git-122.3)
Sridhar Sarnobat 9/03
16

Isso acontece quando você mistura os clientes git do UNIX e do Windows porque o Windows realmente não tem o conceito do bit "x"; portanto, a verificação de um rw-r--r--arquivo (0644) no Windows é "promovida" pela camada POSIX do msys.rwx-r-xr-x (0755) . O git considera que a diferença de modo é basicamente a mesma que a diferença de texto no arquivo, portanto seu patch não se aplica diretamente. Eu acho que a sua única boa opção aqui é para definir core.filemodea false(usando git-config).

Aqui está um problema do msysgit com algumas informações relacionadas: http://code.google.com/p/msysgit/issues/detail?id=164 (redirecionado para a cópia de 3 de dezembro de 2013 de archive.org)

Ben Jackson
fonte
2
Tentei executar o comando "git config core.filemode false", mas não ajudou - ainda estou recebendo a mesma mensagem.
Dmitrii Pisarenko 22/01
Supondo que você não tenha alterações não confirmadas em sua árvore, tente git reset --hard HEADforçar o git a fazer check-out novamente de seus arquivos com a nova opção em vigor.
Ben Jackson
Apenas tentei executar "git reset --hard HEAD". Foi bem-sucedido (vi a mensagem "HEAD is now at ..."), mas o problema com "git apply" persiste.
Dmitrii Pisarenko
7

No meu caso, eu fui estúpido o suficiente para criar o arquivo de correção incorretamente em primeiro lugar, na verdade diferindo da maneira errada . Acabei com exatamente as mesmas mensagens de erro.

Se você é mestre e faz git diff branch-name > branch-name.patchisso, isso tenta remover todas as adições que você deseja que ocorram e vice-versa (que era impossível para o git realizar, pois, obviamente, as adições nunca feitas não podem ser removidas).

Portanto, certifique-se de fazer check-out em sua filial e executar git diff master > branch-name.patch

Ophidian
fonte
3

AVISO: Este comando pode remover confirmações perdidas antigas PERMANENTEMENTE. Faça uma cópia de todo o seu repositório antes de tentar isso.

Eu encontrei este link

Não tenho idéia do porquê disso funcionar, mas tentei muitas soluções alternativas e esse é o único que funcionou para mim. Em resumo, execute os três comandos abaixo:

git fsck --full
git reflog expire --expire=now --all
git gc --prune=now
Archmede
fonte
3
Este é um comando muito perigoso que pode remover os commits perdidos antigos para sempre do reflog. Se seu repositório estiver em um estado instável, NÃO APLIQUE ESTE.
ET
0

O que eu procurei não está exatamente indicado aqui no SO, estou escrevendo para o benefício de outras pessoas que possam procurar por similares. Eu enfrentei um problema com um arquivo (presente no repositório antigo) sendo removido no repositório. E quando aplico o patch, ele falha, pois não conseguiu encontrar o arquivo a ser aplicado. (então, meu caso é que o patch do git falha para que o arquivo seja removido) '#git apply --reject' definitivamente deu uma visão, mas não me levou à correção. Não pude usar o wiggle, pois não está disponível para nós em nossos servidores de compilação. No meu caso, resolvi esse problema removendo a entrada do 'arquivo que foi removido no repositório' do arquivo de correção que tentei aplicar; portanto, todas as outras alterações foram aplicadas sem problemas (usando a combinação de três vias, evitando erros de espaço em branco) e depois mesclar manualmente o conteúdo do arquivo removido para onde ele foi movido.

Bhanu
fonte
0

Meu problema é que eu executei git diff, executei git reset --hard HEADe percebi que queria desfazer, então tentei copiar a saída de git diffum arquivo e usá-lo git apply, mas recebi um erro de que "o patch não se aplica". Depois de mudar para patche tentar usá-lo, percebi que um pedaço do diff foi repetido por algum motivo, e após a remoção do duplicado , patch(e presumivelmente também git apply) trabalhou.

Solomon Ucko
fonte