Wie man einen Patch anwendet und “hunk FAILED”, “can’t find file to patch” und andere löst

von Markus Bertheau, aktualisiert am 1. Dezember 2010 Kommentieren »

Hi :)

Nachdem du diesen Artikel gelesen hast, kannst du Patches/Diffs anwenden und mit auftretenden Fehlern umgehen.

Nehmen wir an, dass der Patch in der Datei fix-bug.patch ist (die Erweiterung hat keinen Einfluß). Das Verzeichnis software-1.0 enthält die Dateien, die gepatcht werden sollen. Ein Patch/Diff wird dann wiefolgt angewandt:

  1. Erstelle ein Backup. Auf Linux kannst du das folgende Kommando verwenden:
    markus@ubuntu:~$ cp -a software-1.0 software-1.0.before-patch
  2. Rufe patch (für Windows: patch.exe) wiefolgt auf:
    markus@ubuntu:~$ patch -Np1 -d software-1.0 < fix-bug.patch

Vorsicht: nach patch kommt minus N p Eins, nicht minus N p kleines L!

Falls das Ergebnis in etwa so aussieht:

markus@ubuntu:~$ patch -Np1 -d software-1.0 < fix-bug.patch
patching file bar.h
patching file quux.c
patching file foo.txt
markus@ubuntu:~$

dann hat es funktioniert und der Patch wurde sauber angewandt.

Falls du andere Ausgaben erhalten hast, können das Warnungen sein, oder Fehlermeldungen. In jedem Fall ist es möglich, dass der Patch nicht richtig oder nur teilweise angewandt wurde. Um sicher zu gehen, stell am besten das Backup wieder her. Danach kümmern wir uns um Warnungen und Fehlermeldungen. Um das Backup unter Linux wieder herzustellen:

markus@ubuntu:~$ rm -rf software-1.0
markus@ubuntu:~$ cp -a software-1.0.before-patch software-1.0
Fehler und wie man sie beseitigt

Hier ist eine Liste von Fehlermeldungen die erscheinen können. Jede Fehlermeldung ist ein Link zu einem Absatz, der beschreibt, wie man den Fehler beseitigt.

can’t find file to patch at input line nnn. File to patch: or
No file to patch. Skipping patch. n out of n hunks ignored.

Überzeuge dich zuerst, dass du den richtigen patch-Befehl benutzt hast, wie oben angegeben.

Falls es trotzdem nicht geht, probiere es mit einem höheren n in -pn, bis zu etwa 6 (du kannst auch noch höhere Zahlen probieren, aber die Wahrscheinlichkeit, dass das Problem eine falsche Zahl für -p ist, wird immer kleiner :) ). Zum Probieren gib noch --dry-run auf der Kommandozeile an. Damit wird der Patch nicht wirklich eingebaut, aber du bekommst alle Warnungen und Fehlermeldungen angezeigt. So kannst du herausfinden ob Fehler auftreten würden, ohne jedes Mal vom Backup wiederherstellen zu müssen. Hier ein Beispiel mit -p2 und --dry-run:

markus@ubuntu:~$ patch --dry-run -Np2 -d software-1.0 < fix-bug.patch

-p0 ist fast immer falsch. Es bewirkt, dass patch Unterverzeichnisse ignoriert und annimmt, dass sich alle Dateien, die gepatcht werden sollen, im gleichen Verzeichnis befinden.

Wenn du keine Fehlermeldungen mit can’t find file to patch oder No file to patch. mehr bekommst, hast du die richtige -p-Zahl gefunden. Falls andere Fehlermeldungen erscheinen, schlage sie in der Liste der Fehlermeldungen nach. Wenn du einen sauberen Durchlauf ohne Fehlermeldungen hast, dann führe den Befehl noch einmal ohne --dry-run aus, um den Patch auch tatsächlich anzuwenden.

Falls das ganze Rumgemache mit -p nicht geholfen hat, und du immernoch die gleiche Fehlermeldung bekommst, schreib einen Kommentar :)

Hunk #n FAILED at nnn. n out of n hunks FAILED — saving rejects to file file.rej

Das bedeutet, dass eine oder mehrere Änderungen, genannt Hunks, nicht in die Datei eingebaut werden konnten. Es gibt einen eher seltenen Grund, der aber am einfachsten zu überprüfen ist: Gib zusätzlich --ignore-whitespace auf der Kommandozeile an, etwa so:

markus@ubuntu:~$ patch -Np1 --ignore-whitespace -d software-1.0 < fix-bug.patch

Falls der Fehler dadurch nicht verschwindet, ist der Grund wahrscheinlich ein anderer: Der Patch wurde für eine andere Softwareversion gemacht, als du benutzt. Es gibt zwei Lösungsmöglichkeiten:

  • Besorge einen Patch für die von dir benutzte Softwareversion, oder benutze die Softwareversion, für die der Patch erstellt wurde.
  • Lasse patch den Kontext einer Änderung ignorieren. Das führt dazu, dass patch eine Änderung eher an einer falschen Stelle einbaut, als einen Fehler auszugeben. Es kann sein, dass die Software dadurch nach dem Patchen nicht richtig funktioniert. Um den Kontext zu ignorieren, benutze zusätzlich -F3:
    markus@ubuntu:~$ patch -Np1 -F3 -d software-1.0 < fix-bug.patch
    
  • Versuche, die Änderungen im Patch von Hand einzubauen.
Hunk #n succeeded at nnn (offset n lines) and
Hunk #n succeeded at nnn with fuzz n.

Normalerweise ist das kein Problem und der Patch wurde komplett eingebaut. Die Nachricht bedeutet, dass der Patch ursprünglich für eine andere Version der Software erstellt wurde, als du benutzt. Es ist aber trotzdem möglich, dass patch eine Änderung falsch eingebaut hat. Falls irgendetwas nicht funktioniert und du denkst, dass der Patch falsch eingebaut sein worden könnte, kannst du die gleiche Softwareversion benutzen, die auch zum Erstellen des Patches benutzt wurde, oder du kannst versuchen, einen Patch für deine Softwareversion zu bekommen.

Du kannst auch die Änderungen im Patch von Hand einbauen und dabei deine einmaligen menschlichen Fertigkeiten einsetzen, um sicherzustellen, dass das Ergebnis Sinn ergibt – etwas, was patch nicht kann :) .

malformed patch at line nnn

Der Patch ist kaputt. Falls du den Patch von irgendwoher kopiert und eingefügt hast, kann es sein, dass der Patch dabei Schaden genommen hat. Eine Patchdatei enthält unter anderem Leerzeichen am Anfang der Zeile – die gehen beim Kopieren über die Zwischenablage oft verloren. Am sichersten ist es, den Patch als Datei herunterzuladen. Falls der Browser den Patch nicht herunterlädt, sondern anzeigt, benutze Datei -> Speichern.

Falls du einen Patch erstellen willst, brauchst du das nicht von Hand zu tun. Das Programm diff tut das automatisch. Eine kurze Anleitung:

  1. Erstelle eine Kopie der originalen, unveränderten Softwareversion. Auf Linux:
    markus@ubuntu:~$ cp -a software-1.0 software-1.0.orig
  2. Mache die Änderungen in software-1.0.
  3. Erstelle den Patch mit diff:
    markus@ubuntu:~$ diff -Naur software-1.0.orig software-1.0 > fix-bug.patch
Reversed (or previously applied) patch detected! Skipping patch.
Reversed (or previously applied) patch detected! Assume -R? [n]

Das bedeutet, dass eine oder mehrere Änderungen des Patches bereits eingebaut sind. Das kann mehrere Gründe haben:

  • Der Ersteller des Patches hat Original und geänderte Version verwechselt. Der Patch ist jetzt rückwärtz – er enthält Änderungen, um aus der neuen Version die Originalversion zu erstellen. Wenn die Änderungen jetzt in die Originalversion eingebaut werden sollen, stellt patch fest, dass alle Änderungen bereits da sind. Netterweise kann ein Patch aber auch rückwärts angewandt werden. Dazu benutzt man -R. Hier ist ein Beispiel:
    markus@ubuntu:~$ patch -RNp1 -d software-1.0 < fix-bug.patch
  • Deine Softwareversion hat tatsächlich bereits alle Änderungen des Patches eingebaut. Vielleicht haben die Ersteller der Software ihrerseits den Patch bereits eingebaut, und die Version, die du heruntergeladen hast, enthält bereits alle Änderungen des Patches.
(Stripping trailing CRs from patch.)

Hier gibt es nichts, worüber man sich Sorgen machen muss. Der Patch wurde sauber eingebaut und alles wird funktionieren. Der wahrscheinlichste Grund für diese Warnung ist, dass der Patch auf Windows erstellt wurde, und du ihn auf Linux anwenden möchtest. Windows und Linux legen Zeilenenden unterschiedlich ab – Windows-Zeilenenden haben ein zusätzliches CR. Die Warnung bedeutet lediglich, dass Windows-Zeilenenden in Linux-Zeilenenden umgewandelt wurden. Hacker benutzen nur für gewöhnlich ihre eigene Sprache, wenn sie Fehlertexte formulieren :)

Fehlermeldung ist hier nicht aufgeführt

Bitte erstelle ein Kommentar mit dem Fehlertext und, falls möglich, einem Link zu dem Patch und einem zu der Software, in die du den Patch einbauen willst. Ich füge dann die Fehlermeldung und eine Erklärung zu dieser Liste hinzu.

Share

Freiwillige Bezahlung

Falls dir dieser Artikel geholfen hat oder dir Zeit oder Geld spart, und du gern dafür bezahlen möchtest, schau dir die Bezahlen-Seite an.

Werbung

Hinterlasse eine Antwort

© 2017 Markus Bertheau. All rights reserved.