git: el parche no se aplica

289

Tengo un parche llamado my_pcc_branch.patch.

Cuando trato de aplicarlo, recibo el siguiente mensaje:

$ 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

Qué significa eso?

¿Como puedo solucionar este problema?

Dmitrii Pisarenko
fuente
¿Hay algún archivo de AbstractedPanel.java.rej por ahí? Típicamente, esto significa que un bot de línea cambió tanto en la fuente como en el parche (aquí la línea 13 parece estar afectada).
Rudi
No, no encontré ningún archivo * .rej.
Dmitrii Pisarenko
No estoy seguro de por qué la respuesta aceptada lo solucionaría (por lo que sospecho que es un arenque rojo), pero ¿no has type 100644, expected 100755implica que hay algún desajuste de permisos chmod en alguna parte?
ruffin

Respuestas:

325

git apply --reject --whitespace=fix mychanges.patch trabajó para mi.

Explicación

La --rejectopción le indicará a git que no falle si no puede determinar cómo aplicar un parche, sino que puede aplicar trozos individuales que puede aplicar y crear archivos de rechazo ( .rej) para los trozos que no puede aplicar. Menear puede "aplicar [estos] parches rechazados y realizar diferencias de palabras".

Adicionalmente, --whitespace=fix advertirá sobre los errores de espacios en blanco e intentará solucionarlos, en lugar de negarse a aplicar un trozo aplicable de otro modo.

Ambas opciones juntas hacen que la aplicación de un parche sea más robusta contra fallas, pero requieren atención adicional con respecto al resultado.

Para toda la documentación, consulte https://git-scm.com/docs/git-apply .

usuario1028904
fuente
8
Esto realmente funcionó mejor para mí porque no modificó completamente mi archivo
Wayne Werner
10
Esto es genial. Simplemente rechaza lo que no puede resolver por sí mismo y luego puede modificar los archivos rechazados manualmente.
Dennis
1
patch -p1 <mychanges.patch # aplica cambios parte por parte. Si los cambios fallan, se crea un parche <sourcefile> .orig y <sourcefile> .rej y puede aplicar los cambios manualmente. Supongo que git apply --reject hace lo mismo y --whitespace = fix es mágicamente mejor.
gaoithe
77
Este comando crea .rejarchivos cuando no puede detectar automáticamente cómo aplicar un parche. Podrías usar wiggle para resolver tales problemas.
goodniceweb
14
Esta respuesta no explica nada, en particular en qué casos funcionará. Gente, realmente tienes que ser más exigente con la calidad de respuesta, esto NO es un foro.
Oliver
319

Johannes Sixt de la lista de correo [email protected] sugirió usar los siguientes argumentos de línea de comando:

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

Esto resolvió mi problema.

Dmitrii Pisarenko
fuente
25
¿Alguien puede ayudarme y explicar por qué esto funciona? La otra respuesta no funcionó para mí, y tuve exactamente el mismo problema que el que hace la pregunta. ¿Qué tienen que ver los atributos de archivo con ignorar los espacios en blanco?
skrebbel
1
Uso de Windows Powershell Un parche hecho con git diff se aplicó con éxito de la siguiente manera: git diff HEAD..613fee - myfile.xml | git apply --ignore-space-change --ignore-whitespace, mientras que primero guardar el resultado de diff como un archivo no funcionó, en caso de que alguien tenga el mismo problema
tjb
2
También intente -C1cambiar para aplicar, reduce el contexto en torno a las adiciones que se consideran importantes.
Amir Ali Akbari
2
@EricWalker, la magia git con CR / LF no es necesariamente algo malo. La alternativa puede ser que la mitad de sus conjuntos de cambios consiste en que cada línea en cada archivo que se tocó se cambie de una línea que termina a la otra, con el cambio real enterrado en algún lugar en el medio.
jwg
3
Esto ayuda a veces. Pero otras veces, sigo teniendo el "parche no se aplica", aunque el parche debería aplicarse sin problemas.
Thomas Levesque
118

Cuando todo lo demás falla, prueba git applyla --3wayopción .

git apply --3way patchFile.patch

- 3 vías
Cuando el parche no se aplica limpiamente, recurra a la combinación de 3 vías si el parche registra la identidad de los blobs a los que se supone que se aplica, y tenemos esos blobs disponibles localmente, posiblemente dejando los marcadores de conflicto en los archivos en El árbol de trabajo para que el usuario lo resuelva. Esta opción implica la opción --index, y es incompatible con las opciones --reject y --cached.

El caso típico de falla aplica la mayor cantidad de parche que puede y te deja con conflictos para resolver en git como de costumbre lo haces. Probablemente un paso más fácil que la rejectalternativa.

ruffin
fuente
2
Esta es la respuesta que funcionó para mí. El archivo que estaba revisando no reflejaba los cambios desde los que generé el parche (porque eliminé los cambios después de crear el parche)
Christia
3
Buena solución general. El 3way diff no parecía que normalmente estuviera un poco confundido por eso, pero sin embargo esto me dio la capacidad de resolver el conflicto y obtener el parche para aplicarlo.
steinybot
8
Creo que este --3waydebería ser el comportamiento predeterminado. Cuando el parche falla, al menos dime qué falló para que pueda solucionarlo manualmente. git applysimplemente falla y no informa por qué algo falla. Ni siquiera pude encontrar *.rejarchivos como los que hggenera.
Pavan Manjunath
44
Definitivamente, la mejor solución. ¡Deje que el usuario resuelva sus propios conflictos!
Mosh Feu
56

Este comando aplicará el parche sin resolverlo, dejando archivos incorrectos como *.rej:

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

Solo tienes que resolverlos. Una vez resuelto ejecutar:

git -am resolved
Ivan Voroshilin
fuente
77
cómo resolverlo *.rej: todo lo que puedo encontrar es hacer los cambios manualmente en el archivo fuente y eliminar estos .rejarchivos. Cualquier otra forma ?
coding_idiot
1
@coding_idiot Como de costumbre, solo verifique los archivos .rej, compárelos con los archivos en conflicto y finalmente agregue los archivos fijos al índice (con "git add FIXED_FILES")
Ivan Voroshilin
2
@coding_idiot, puede usar wiggle para resolverlo. Por ejemplo: wiggle --replace path/to/file path/to/file.rej. Este comando aplicará los cambios del .rejarchivo al archivo original. También crea una copia del archivo original, como path/to/file.porig. Por favor, consulte la documentación para obtener más información sobre wiggle
goodniceweb
22

Intente usar la solución sugerida aquí: https://www.drupal.org/node/1129120

patch -p1 < example.patch

Esto me ayudo.

Pini Cheyni
fuente
3
Sé que se supone que no debes hacer esto, pero ¡MUCHAS GRACIAS! Me salvó horas. Estaba recibiendo "el parche no se aplica" y todo tipo de errores.
sudo rm -rf slash
@ sudorm-rfslash, ¿por qué se supone que no debemos hacer esto y por qué lo hiciste?
Negro
git: 'patch' is not a git command.engit version 2.21.1 (Apple Git-122.3)
Sridhar Sarnobat
16

Ocurre cuando se mezclan clientes git de UNIX y Windows porque Windows realmente no tiene el concepto del bit "x", por lo que la rw-r--r--extracción de un archivo (0644) en Windows es "promovida" por la capa POSIX de rwx-r-xr-xmsys para que sea (0755) . git considera que la diferencia de modo es básicamente la misma que una diferencia textual en el archivo, por lo que su parche no se aplica directamente. Creo que su única buena opción aquí es fijar core.filemodea false(usandogit-config ).

Aquí hay un problema de msysgit con información relacionada: http://code.google.com/p/msysgit/issues/detail?id=164 (redirigido a la copia del 3 de diciembre de 2013 de archive.org)

Ben Jackson
fuente
2
Traté de ejecutar el comando "git config core.filemode false", pero no me ayudó, sigo recibiendo el mismo mensaje.
Dmitrii Pisarenko
Suponiendo que no tiene cambios no confirmados en su árbol, intente git reset --hard HEADforzar a git a volver a pagar sus archivos con la nueva opción vigente.
Ben Jackson
Acabo de probar ejecutar "git reset --hard HEAD". Tuvo éxito (vi el mensaje "HEAD está ahora en ..."), pero el problema con "git apply" persiste.
Dmitrii Pisarenko
7

En mi caso, fui lo suficientemente estúpido como para crear el archivo de parche incorrectamente en primer lugar, en realidad difería de la manera incorrecta . Terminé con exactamente los mismos mensajes de error.

Si está en master y do git diff branch-name > branch-name.patch, esto intenta eliminar todas las adiciones que desea que sucedan y viceversa (lo cual fue imposible para git ya que, obviamente, las adiciones que nunca se hicieron no se pueden eliminar).

Así que asegúrese de pagar a su sucursal y ejecutar git diff master > branch-name.patch

Ofidia
fuente
3

ADVERTENCIA: Este comando puede eliminar las confirmaciones perdidas antiguas PERMANENTEMENTE. Haga una copia de todo su repositorio antes de intentar esto.

He encontrado este enlace

No tengo idea de por qué funciona, pero probé muchas soluciones y esta es la única que funcionó para mí. En resumen, ejecute los tres comandos a continuación:

git fsck --full
git reflog expire --expire=now --all
git gc --prune=now
Archmede
fuente
3
Este es un comando muy peligroso que puede eliminar las viejas confirmaciones perdidas para siempre del reflog. Si su repositorio está en un estado inestable, NO APLIQUE ESTO.
ET
0

Lo que busqué no se señala exactamente aquí en SO, estoy escribiendo para beneficio de otros que podrían buscar algo similar. Me enfrenté a un problema con un archivo (presente en el repositorio anterior) que se eliminaba en el repositorio. Y cuando aplico el parche, falla ya que no pudo encontrar el archivo que se aplicará. (así que mi caso es que el parche git falla porque el archivo se eliminó) '#git apply --reject' definitivamente dio una vista, pero no me ayudó a solucionarlo. No pude usar wiggle ya que no está disponible para nosotros en nuestros servidores de compilación. En mi caso, resolví este problema al eliminar la entrada del 'archivo que se eliminó en el repositorio' del archivo de parche que intenté aplicar, por lo que obtuve todos los demás cambios aplicados sin problemas (usando la combinación de 3 vías, evitando errores de espacio en blanco), y luego fusionando manualmente el contenido del archivo eliminado en donde se movió.

Bhanu
fuente
0

Mi problema es que ejecuté git diff, luego ejecuté git reset --hard HEAD, luego me di cuenta de que quería deshacer, así que intenté copiar el resultado de git diffun archivo y usarlo git apply, pero recibí un error que indica que "el parche no se aplica". Después de cambiar patche intentar usarlo, me di cuenta de que una parte del diff se repitió por alguna razón, y después de eliminar el duplicado , patch(y presumiblemente también git apply) funcionó.

Solomon Ucko
fuente