web-dev-qa-db-fra.com

git-apply échoue mystérieusement, comment puis-je dépanner / réparer?

J'essaie actuellement de vérifier le style de code sur les PR d'un référentiel (github), et je veux fournir aux correcteurs des correctifs avec lesquels ils peuvent facilement corriger le codestyle. À cette fin, je déroule leur PR, exécute notre script uncrustify dessus pour corriger les erreurs de style et souhaite créer un fichier .patch qu'ils peuvent facilement appliquer. Cependant, il casse systématiquement certains fichiers.

Je le fais (git version 1.7.10.4 avec core.autocrlf=input, core.filemode=false):

$ git checkout pr-branch
$ git log -1 (shows: commit dbb8d3f)
$ git status (nothing to commit, working directory clean)
$ <run the code styler script, which modifies some files>
$ git diff > ../style.patch (so the patch file lands outside the repo)
$ git reset --hard HEAD (to simulate the situation at the submitter's end)
$ git log -1 (shows: commit dbb8d3f)
$ git status (nothing to commit, working directory clean, so we are where we started)
$ git apply ../style.patch
error: patch failed: somefile.cpp:195
error: somefile.cpp: patch does not apply (same output using the --check option)

Cela ne s'applique qu'à certains fichiers, pas à tous. Je ne sais pas comment résoudre ce problème, c'est-à-dire comment faire en sorte que Git me dise exactement où ça va mal - cela ne me dit qu'un morceau # quand je creuse, mais c'est toujours assez énorme.

Ce que j'ai essayé jusqu'à présent (sans succès):

  1. apply --reverse, apply --whitespace=nowarn
  2. diff HEAD au lieu de diff seul
  3. faire un commit factice (la validation des travaux sans problème!), utilisez format-patch, supprimez le commit factice, appliquez le correctif avec git-am avec ou sans -3, ou postulez avec git-apply
  4. Ayez le fichier de patch dans le répertoire local au lieu d'un (place à la paille, ici)
  5. Consultez les pages de manuel de git-diff, -apply, -format-patch, -am pour tout ce qui est utile
  6. patch avec la commande linux patch
  7. ....

Je ne sais pas ce qui pourrait mal avec le diff. Les choses en blanc devraient seulement avertir, non? En tout cas, je ne veux pas les ignorer, car c'est une correction de style qui implique évidemment des espaces.

Comment puis-je résoudre/diagnostiquer cela ou même savoir où cela échoue exactement? Serait-il utile que je publie le diff de l'un des fichiers coupables? Ce qui me déroute aussi, c'est que le commit fonctionne sans problème, mais le patch créé à partir du commit ne fonctionne pas ??

Après avoir lutté avec ça pendant plusieurs heures, je suis au bout de mes connaissances ...

31
Christoph

Mise à jour:

Vous pouvez utiliser git apply -v pour voir des informations plus détaillées sur ce qui se passe, git apply --check pour simplement vérifier l'opération, ou git apply --index pour reconstruire le fichier d'index local.

Sur la base de votre commentaire, il semble que votre index local ait été corrompu, et donc index l'a résolu.

Je vais laisser ma réponse originale et les commentaires principalement pour donner aux gens un contexte sur ce qui se passait, car je soupçonne que d'autres personnes sauteraient aux mêmes conclusions initiales que j'avais basées sur la description du problème.

------

Il n'y a probablement rien de mal avec le diff. Regardez plutôt le référentiel git cible. Pendant que vous faites git reset --hard HEAD, rien ne vous garantit que le HEAD sur cet autre référentiel est le même que le HEAD sur votre.

Faire git log sur le référentiel cible et regardez le commit en haut. Est-ce la même que celle dont vous avez produit le diff? Ce n'est probablement pas le cas. Parcourez l'historique et vérifiez si le commit dont vous avez besoin est là. Si c'est le cas, le référentiel cible est en avance sur le vôtre et vous devez revenir en arrière, faites git pull (ou git rebase) et produire un nouveau diff. Si ce n'est pas le cas, le référentiel cible est derrière le vôtre et vous devez faire git pull (ou git rebase) sur le référentiel cible pour l'actualiser.

Gardez à l'esprit que si d'autres personnes s'engagent dans votre référentiel "maître" (celui d'où proviennent les vôtres et les référentiels cibles), vous devrez peut-être git pull les deux référentiels, pour les amener à un commit commun raisonnablement récent.

32
Franci Penov

Essayez de vérifier votre fichier de correctif - exemple:

git apply --reject mypatch.patch

cela vous montrera les différences éventuelles - voici un exemple de la façon dont cela pourrait ressembler:

error: patch failed: <filename>:<linenumber>
error: while searching for :
    cout << "}" << endl; // example of a line in your patch
7
serup