Wie erstelle ich einen Patch für ein ganzes Verzeichnis, um es zu aktualisieren?

74

Ich weiß , es gibt mehrere Threads zu diesem bereits, aber niemand hat genau ausführlich erklärt , wie die anfängliche diff auszuführen , um die Patch - Datei zu erstellen, dann , wie gelten , dass Patch auf das ursprüngliche Verzeichnis , sich zu aktualisieren.

In meinem Fall gibt es ein Verzeichnis mit Dateien, die jeder aus dem Internet herunterladen kann. Ich habe dieses Verzeichnis übernommen und Änderungen daran vorgenommen und möchte eine Patch-Datei erstellen, damit andere sie auf das heruntergeladene Verzeichnis anwenden können, um genau das zu reproduzieren, was ich in meinem geänderten Verzeichnis habe.

Hilfe? Was muss ich der anderen Person bezüglich der Anwendung meines Patches sagen?

Poundifdef
quelle

Antworten:

143

Ich hatte gerade das gleiche Problem - viele Ratschläge, wie man es zur Hälfte macht. Nun, hier ist, was ich getan habe, um sowohl das Patchen als auch das Entpacken zum Laufen zu bringen:

So erstellen Sie die Patch-Datei:

  1. Legen Sie Kopien beider Verzeichnisse in say / tmp ab, damit wir die Patch-Datei erstellen können, oder holen Sie sie, wenn Sie mutig sind, nebeneinander ab - in einem Verzeichnis.

  2. Führen Sie einen entsprechenden Diff für die beiden Verzeichnisse alt und neu aus:

    diff -ruN orig/ new/ > file.patch
    # -r == recursive, so do subdirectories
    # -u == unified style, if your system lacks it or if recipient
    #       may not have it, use "-c"
    # -N == treat absent files as empty
    

Wenn eine Person über das orig / -Verzeichnis verfügt, kann sie das neue Verzeichnis durch Ausführen eines Patches neu erstellen.

So erstellen Sie den neuen Ordner aus dem alten Ordner und der Patch-Datei neu:

  1. Verschieben Sie die Patch-Datei in ein Verzeichnis, in dem der Ordner orig / vorhanden ist

  2. Dieser Ordner wird überfüllt sein. Bewahren Sie daher irgendwo ein Backup auf oder verwenden Sie eine Kopie.

    patch -s -p0 < file.patch
    # -s == silent except errors
    # -p0 == needed to find the proper folder
    
  3. Zu diesem Zeitpunkt enthält der Ordner orig / den neuen / content, hat aber immer noch seinen alten Namen.

    mv orig/ new/    # if the folder names are different
    
David H.
quelle
7
Ich wünschte, ich könnte dir die Hand geben. Vielen Dank!
Poundifdef
1
Ich bin ein Mac-Typ, also keine Ahnung. Was Sie tun müssen, ist die Optionen für Patch und Diff auf Cygwin zu überprüfen. Aus diesem Grund habe ich die obigen Kommentare zur Bedeutung der Optionen hinzugefügt. Wenn also das eine oder andere Programm unterschiedliche Optionen bietet, können Sie herausfinden, was geändert werden muss, damit es funktioniert. Konzeptionell sollten alle Patch / Diff-Programme die Funktionalität unterstützen.
David H
@CharanPai "diff" unterstützt keine Binärdateien, daher nehme ich nicht an. Möglicherweise können Sie dazu Ihren eigenen Befehlsdatei-Wrapper erstellen. Was Sie tun würden, ist Ihre Binärdatendateien binhex - erstellen Sie für jede eine Textdatei im Binhex- oder ähnlichen ASCII-Format. Dann unterscheiden Sie diese Dateien, und nachdem der Patch angewendet wurde, lösen Sie die (möglicherweise überarbeitete) Binhex-Datei in binär.
David H
nein, -a würde dafür arbeiten. behandelt alle Dateien als Text.
Charan Pai
2
patchwar das Patchen new/nicht orig/Verzeichnis für mich, aber ich fand -dOption , die Sie sagen können cdin das Verzeichnis vor dem Anwenden des Patch zuerst und dann können Sie das einstellen -p NArgument entsprechend.
Dramzy
3

Ich musste eine Patch-Datei erstellen und an jemanden senden, damit dieser sein Verzeichnis entsprechend meinem aktualisieren konnte. Es gibt jedoch viele Einschränkungen bei Diff und Patch , so dass ich Stunden gebraucht habe, um etwas so konzeptionell Einfaches herauszufinden. Absolute Pfade scheinen relativen Pfaden vorzuziehen, und viele der Optionen scheinen sich aus Nischenanwendungsfällen entwickelt zu haben. Ich habe schließlich eine Lösung gefunden, die auf der Antwort von David H basiert , mit zusätzlichen Tipps von Lakshmanan Ganapathy ):

  • Sichern Sie Ihre directoryzudirectory.orig
  • Ändern Sie Ihre directory, um den gewünschten Status zu erreichen
  • Speichern Sie den Unterschied von directory.origbis directoryin, file.patchdamit der Name mit dem Empfänger übereinstimmt

Hier sind meine Notizen:

# to create patch:
# copy <directory> backup to something like <directory>.orig alongside it
cp -r <path_to>/<directory> <path_to>/<directory>.orig
# create/update/delete files/folders in <directory> until desired state is reached
# change working directory to <directory>
cd <path_to>/<directory>
# create patch file alongside <directory>
diff -Naru ../<directory>.orig . > ../file.patch
# -N --new-file Treat absent files as empty.
# -a --text Treat all files as text.
# -r --recursive Recursively compare any subdirectories found.
# -u -U NUM --unified[=NUM] Output NUM (default 3) lines of unified context.

# to apply patch:
# change working directory to <directory>
cd <path_to>/<directory>
patch -s -p0 < <path_to>/file.patch
# -s or --silent or --quiet Work silently, unless an error occurs.
# -pN or --strip=N Strip smallest prefix containing num leading slashes from files.

# to undo patch (note that directories created by patch must be removed manually):
# change working directory to <directory>
cd <path_to>/<directory>
patch -Rs -p0 < <path_to>/file.patch
# -R or --reverse Assume that patch was created with the old and new files swapped.
# -s or --silent or --quiet Work silently, unless an error occurs.
# -pN or --strip=N Strip smallest prefix containing num leading slashes from files.
Zack Morris
quelle
2

Schauen Sie sich die Open Source Scarab C ++ - Bibliothek an: https://github.com/loyso/Scarab

Es macht genau das, was Sie beschrieben haben. Es erstellt eine Datei pro Datei mithilfe der xdelta-Bibliothek und legt sie im Archivpaket ab. Sie können dieses Paket neu verteilen und die Differenz anwenden. Es gibt Binärdateien für Win32.

Ich bin der Autor des Scarab-Projekts.

Alexey Baskakov
quelle