webentwicklung-frage-antwort-db.com.de

Wie wende ich einen Git-Patch auf eine Datei mit einem anderen Namen und Pfad an?

Ich habe zwei Repositories. In einem Fall ändere ich die Datei ./hello.test. Ich übergebe die Änderungen und erstelle mit git format-patch -1 HEAD einen Patch aus diesem Commit. Jetzt habe ich ein zweites Repository, das eine Datei enthält, die den gleichen Inhalt wie hello.test hat, sich aber in einem anderen Verzeichnis unter einem anderen Namen befindet: ./blue/red/hi.test. Wie gehe ich vor, um den oben genannten Patch auf die hi.test-Datei anzuwenden? Ich habe git am --directory='blue/red' < patch_file ausprobiert, aber das beschwert sich natürlich, dass die Dateien nicht gleich benannt werden (was ich für Git nicht interessierte?). Ich weiß, dass ich möglicherweise den Diff bearbeiten könnte, um auf diese bestimmte Datei anzuwenden, aber ich suche nach einer Befehlslösung.

68
mart1n

Sie können den Patch mit git diff erstellen und ihn dann mit dem patch -Dienstprogramm anwenden, mit dem Sie die Datei angeben können, auf die Sie den Diff anwenden möchten.

Zum Beispiel:

cd first-repo
git diff HEAD^ -- hello.test > ~/patch_file

cd ../second-repo
patch -p1 blue/red/hi.test ~/patch_file
70
georgebrock

Es gibt eine einfache Lösung, die keine manuelle Bearbeitung von Patches oder externen Skripts umfasst. 

Im ersten Repository (dies kann auch einen Commit-Bereich exportieren, verwenden Sie -1, wenn Sie nur ein Commit auswählen möchten):

git format-patch --relative <committish> --stdout > ~/patch

Im zweiten Repository:

git am --directory blue/red/ ~/patch

Anstatt --relative in git format-patch zu verwenden, besteht eine andere Lösung darin, die -p<n>-Option in git am zu verwenden, um n-Verzeichnisse aus dem Pfad der Patches zu entfernen, wie in einer Antwort auf eine ähnliche Frage erwähnt.

Es ist auch möglich, git format-patch --relative <committish> ohne --stdout auszuführen, und es wird ein Satz von .patch-Dateien generiert. Diese Dateien können dann mit git am direkt an git am --directory blue/red/ path/to/*.patch übergeben werden.

31
magiraud

Beantworten meiner eigenen Frage mit einem Skript, das genau dies tut: https://github.com/mprpic/apply-patch-to-file

Anstatt die Patch-Datei manuell zu ändern, fordert sie den Benutzer zur Eingabe der Zieldatei auf, ändert den Patch und wendet ihn auf das derzeitige Repo an.

8
mart1n

Aufbauend auf der Antwort von @georgebrock habe ich hier eine Lösung verwendet:

Erstellen Sie zuerst die Patch-Dateien wie gewohnt (zB git format-patch commitA..commitB).

Stellen Sie dann sicher, dass Ihr Ziel-Repository sauber ist (es sollten keine geänderten oder nicht protokollierten Dateien vorhanden sein), und wenden Sie die Patches wie folgt an:

cd second-repo
git am ~/00*.patch

Für jede Patch-Datei erhalten Sie eine Fehlermeldung wie "Fehler: XYZ ist nicht im Index vorhanden". Sie können diese Patchdatei jetzt manuell anwenden:

patch --directory blue/red < ~/0001-*.patch
git add -a
git am --continue

Sie müssen diese drei Schritte für jede Patchdatei ausführen.

Dadurch wird die ursprüngliche Festschreibungsnachricht usw. beibehalten, ohne dass ein besonderer git format-patch-Befehl oder das Bearbeiten der Patch-Dateien erforderlich ist.

1
oliver

Ich verstehe, dass die beiden Dateien in Ihrer Situation genau gleich sind, daher ist der Patch wahrscheinlich erfolgreich.

Wenn Sie jedoch einen Patch auf eine ähnliche, aber nicht genau dieselbe Datei anwenden oder ein interaktives Patching ausführen möchten, verwenden Sie die Drei-Wege-Zusammenführung.

Angenommen, Sie haben die Datei A geändert, dann bezeichnen wir A~1 als Vorgängerversion, und Sie möchten den Unterschied zwischen A~1 zu A zu Datei B.

Öffnen Sie ein Drei-Wege-Zusammenführungswerkzeug, zum Beispiel Beyond Compare, der Pfad des linken Fensters ist A, das mittlere Fenster ist der gemeinsame Vorfahr, der Pfad ist also A~1, der Pfad des rechten Fensters ist B. Dann zeigt das untere Feld das Ergebnis der Anwendung des Unterschieds zwischen A~1 zu A zu Datei B.

Die folgende Abbildung veranschaulicht die Idee.

enter image description here

0
Gqqnbig