git: le patch ne s'applique pas

289

J'ai un certain correctif appelé my_pcc_branch.patch.

Lorsque j'essaie de l'appliquer, je reçois le message suivant:

$ 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'est-ce que ça veut dire?

Comment puis-je résoudre ce problème?

Dmitrii Pisarenko
la source
Y a-t-il des fichiers AbstractedPanel.java.rej qui traînent? Typiquement, cela signifie qu'un bot de ligne a changé dans la source ainsi que dans le patch (ici, la ligne 13 semble être affectée).
Rudi
Non, je n'ai trouvé aucun fichier * .rej.
Dmitrii Pisarenko,
Vous ne savez pas pourquoi la réponse acceptée le corrigerait (donc je soupçonne que c'est un hareng rouge), mais cela ne has type 100644, expected 100755signifie pas qu'il y a une incompatibilité des autorisations chmod quelque part?
ruffin

Réponses:

325

git apply --reject --whitespace=fix mychanges.patch travaillé pour moi.

Explication

L' --rejectoption demandera à git de ne pas échouer s'il ne peut pas déterminer comment appliquer un correctif, mais plutôt d'appliquer des morceaux individuels qu'il peut appliquer et de créer des fichiers de rejet ( .rej) pour les morceaux qu'il ne peut pas appliquer. Wiggle peut "appliquer [ces] correctifs rejetés et effectuer des différences au niveau des mots".

De plus, vous --whitespace=fixavertira des erreurs d'espace et essaiera de les corriger, plutôt que de refuser d'appliquer un morceau par ailleurs applicable.

Ensemble, les deux options rendent l'application d'un correctif plus robuste contre les pannes, mais elles nécessitent une attention supplémentaire en ce qui concerne le résultat.

Pour toute la documentation, voir https://git-scm.com/docs/git-apply .

user1028904
la source
8
En fait, cela a mieux fonctionné pour moi car cela n'a pas complètement modifié mon fichier
Wayne Werner
10
C'est bien. Rejette simplement ce qu'il ne peut pas résoudre lui-même et vous pouvez ensuite simplement modifier manuellement les fichiers rejetés.
Dennis
1
patch -p1 <mychanges.patch # applique les modifications morceau par morceau. Si les modifications échouent, un correctif <sourcefile> .orig et <sourcefile> .rej est créé et vous pouvez appliquer les modifications manuellement. Je suppose que git s'applique - reject fait de même et --whitespace = fix est magiquement meilleur.
gaoithe
7
cette commande crée des .rejfichiers quand ne peut pas détecter automatiquement comment appliquer un patch. Vous pouvez utiliser wiggle pour résoudre ces problèmes.
goodniceweb
14
Cette réponse n'explique rien, en particulier dans quels cas cela fonctionnera. Les gens, il faut vraiment être plus exigeant sur la qualité des réponses, ce n'est donc PAS un forum.
Oliver
319

Johannes Sixt de la liste de diffusion [email protected] a suggéré d'utiliser les arguments de ligne de commande suivants:

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

Cela a résolu mon problème.

Dmitrii Pisarenko
la source
25
Quelqu'un peut-il m'aider et expliquer pourquoi cela fonctionne? L'autre réponse n'a pas fonctionné pour moi, et j'ai eu exactement le même problème que ce que le demandeur de questions décrit. Qu'est-ce que les attributs de fichier ont à voir avec l'ignorance des espaces?
skrebbel
1
Utilisation de windows powershell Un correctif créé avec git diff a été appliqué avec succès comme suit: git diff HEAD..613fee - myfile.xml | git apply --ignore-space-change --ignore-whitespace, alors que la première sauvegarde de la sortie diff en tant que fichier ne fonctionnait pas, au cas où quelqu'un rencontrerait le même problème
tjb
2
essayez également de -C1basculer pour appliquer, cela réduit le contexte des ajouts qui sont considérés comme importants.
Amir Ali Akbari
2
@EricWalker, git magic avec CR / LF n'est pas nécessairement une mauvaise chose. L'alternative peut être que la moitié de vos ensembles de modifications consiste en ce que chaque ligne de chaque fichier qui a été touché est modifiée d'une ligne se terminant à l'autre, avec le changement réel enterré quelque part au milieu.
jwg
3
Cela aide parfois. Mais d'autres fois, j'obtiens toujours le «patch ne s'applique pas», même si le patch devrait s'appliquer sans problème.
Thomas Levesque
118

Lorsque tout le reste échoue, essayez git applyl' --3wayoption .

git apply --3way patchFile.patch

--3way
Lorsque le patch ne s'applique pas correctement, retombez sur la fusion à 3 si le patch enregistre l'identité des blobs auxquels il est censé s'appliquer, et nous avons ces blobs disponibles localement, laissant éventuellement les marqueurs de conflit dans les fichiers dans l'arborescence de travail que l'utilisateur doit résoudre. Cette option implique l'option --index et est incompatible avec les options --reject et --cached.

Le cas d'échec typique applique autant de correctifs que possible et vous laisse avec des conflits à résoudre dans git comme vous le faites normalement. Probablement une étape plus facile que l' rejectalternative.

ruffin
la source
2
C'est la réponse qui a fonctionné pour moi. Le fichier que j'effectuais ne reflétait pas les modifications à partir desquelles j'avais généré le correctif (car j'ai supprimé les modifications après avoir créé le correctif.)
Christia
3
Belle solution générale. Le diff 3way ne ressemblait pas à ce qu'il fait normalement, donc un peu confus, mais cela m'a néanmoins donné la possibilité de résoudre le conflit et d'obtenir le patch à appliquer.
steinybot
8
Je pense que cela --3waydevrait être le comportement par défaut. Lorsque le patch échoue, dites-moi au moins ce qui a échoué afin que je puisse le réparer manuellement. git applyéchoue et ne signale pas pourquoi quelque chose échoue. Je n'ai même pas pu trouver de *.rejfichiers comme ceux hggénérés.
Pavan Manjunath
4
Certainement, la meilleure solution. Laissez l'utilisateur résoudre ses propres conflits!
Mosh Feu
56

Cette commande appliquera le correctif sans le résoudre en laissant des fichiers incorrects comme *.rej:

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

Il vous suffit de les résoudre. Une fois résolu, exécutez:

git -am resolved
Ivan Voroshilin
la source
7
comment résoudre *.rej- tout ce que je peux trouver est de faire les modifications manuellement dans le fichier source et de supprimer ces .rejfichiers. De toute autre manière?
coding_idiot
1
@coding_idiot Comme d'habitude, il suffit de vérifier les fichiers .rej, de les comparer avec les fichiers en conflit et enfin d'ajouter les fichiers fixes à l'index (avec "git add FIXED_FILES")
Ivan Voroshilin
2
@coding_idiot vous pouvez utiliser wiggle pour le résoudre. Par exemple: wiggle --replace path/to/file path/to/file.rej. Cette commande appliquera les modifications du .rejfichier au fichier d'origine. Il crée également une copie du fichier d'origine, comme path/to/file.porig. S'il vous plaît, consultez la documentation pour obtenir plus d'informations sur wiggle
goodniceweb
22

Essayez d'utiliser la solution suggérée ici: https://www.drupal.org/node/1129120

patch -p1 < example.patch

Cela m'a aidé.

Pini Cheyni
la source
3
Je sais que tu n'es pas censé faire ça, mais MERCI BEAUCOUP! M'a sauvé des heures. J'obtenais «le patch ne s'applique pas» et toutes sortes d'erreurs.
sudo rm -rf slash
@ sudorm-rfslash, pourquoi ne sommes-nous pas censés faire cela et pourquoi le faisiez-vous quand même?
Black
git: 'patch' is not a git command.legit version 2.21.1 (Apple Git-122.3)
Sridhar Sarnobat
16

Cela se produit lorsque vous mélangez des clients git UNIX et Windows parce que Windows n'a pas vraiment le concept du bit "x", donc votre extraction d'un rw-r--r--fichier (0644) sous Windows est "promue" par la couche POSIX msys pour être rwx-r-xr-x(0755) . git considère que la différence de mode est fondamentalement la même qu'une différence textuelle dans le fichier, donc votre patch ne s'applique pas directement. Je pense que votre seule bonne option est de mettre ici core.filemodeà false( en utilisant git-config).

Voici un problème msysgit avec des informations connexes: http://code.google.com/p/msysgit/issues/detail?id=164 (redirigé vers la copie du 3 décembre 2013 d'Archive.org)

Ben Jackson
la source
2
J'ai essayé d'exécuter la commande "git config core.filemode false", mais cela n'a pas aidé - je reçois toujours le même message.
Dmitrii Pisarenko,
En supposant que vous n'ayez aucune modification non validée dans votre arborescence, essayez git reset --hard HEADde forcer git à récupérer vos fichiers avec la nouvelle option en vigueur.
Ben Jackson
Je viens de l'essayer, exécutez "git reset --hard HEAD". Il a réussi (j'ai vu le message "HEAD is now at ..."), mais le problème avec "git apply" persiste.
Dmitrii Pisarenko
7

Dans mon cas, j'ai été assez stupide pour créer le fichier correctif de manière incorrecte en premier lieu, ce qui diffère en fait de la mauvaise façon . Je me suis retrouvé avec exactement les mêmes messages d'erreur.

Si vous êtes maître et que vous le faites git diff branch-name > branch-name.patch, cela essaie de supprimer tous les ajouts que vous souhaitez effectuer et vice versa (ce qui était impossible pour git car, évidemment, les ajouts jamais effectués ne peuvent pas être supprimés).

Assurez-vous donc de passer à la caisse de votre succursale et d'exécuter git diff master > branch-name.patch

Ophidian
la source
3

AVERTISSEMENT: cette commande peut supprimer les anciennes validations perdues de façon PERMANENTE. Faites une copie de l'intégralité de votre référentiel avant d'essayer.

J'ai trouvé ce lien

Je ne sais pas pourquoi cela fonctionne mais j'ai essayé de nombreux contournements et c'est le seul qui a fonctionné pour moi. En bref, exécutez les trois commandes ci-dessous:

git fsck --full
git reflog expire --expire=now --all
git gc --prune=now
Archmède
la source
3
Il s'agit d'une commande très dangereuse qui peut supprimer définitivement les anciens commits perdus du reflog. Si votre dépôt est dans un état fragile, NE PAS APPLIQUER CECI.
ET
0

Ce que je cherchais n'est pas exactement indiqué ici dans SO, j'écris pour le bénéfice d'autres qui pourraient rechercher des similaires. J'ai rencontré un problème avec un fichier (présent dans l'ancien référentiel) supprimé dans le référentiel. Et lorsque j'applique le correctif, il échoue car il n'a pas pu trouver le fichier à appliquer. (donc mon cas est que le patch git échoue car le fichier a été supprimé) '#git apply --reject' a définitivement donné une vue mais ne m'a pas tout à fait apporté au correctif. Je ne pouvais pas utiliser wiggle car il n'est pas disponible pour nous dans nos serveurs de build. Dans mon cas, j'ai surmonté ce problème en supprimant l'entrée du `` fichier qui a été supprimé dans le référentiel '' du fichier de correctif que j'ai essayé d'appliquer, j'ai donc appliqué toutes les autres modifications sans problème (en utilisant la fusion à 3 voies, en évitant erreurs d'espace blanc), puis fusionner manuellement le contenu du fichier supprimé à l'endroit où il a été déplacé.

Bhanu
la source
0

Mon problème est que j'ai couru git diff, puis couru git reset --hard HEAD, puis réalisé que je voulais annuler, j'ai donc essayé de copier la sortie de git diffdans un fichier et de l'utiliser git apply, mais j'ai eu une erreur que "le patch ne s'applique pas". Après le passage à patchet essayer de l' utiliser, je me suis aperçu qu'un morceau du différentiel a été répété pour une raison quelconque, et après avoir enlevé le double , patch(et sans doute aussi git apply) travaillé.

Solomon Ucko
la source