Wie speichere ich geänderte Dateien?

8

Ich habe zwei Ordner:

  • ORIGINAL/
  • ORIGINAL_AND_MY_CHANGES /

Mein Freund hat eine Kopie von ORIGINAL /. Ich möchte MY_CHANGES.tgz generieren - es sollte nur neue / geänderte Dateien von ORIGINAL_AND_MY_CHANGES / im Vergleich zu ORIGINAL / enthalten. Mein Freund kann es also in seine Kopie von ORIGINAL / auspacken und ORIGINAL_AND_MY_CHANGES / erhalten. Wie kann ich das machen?

PS Ich habe es versucht, diffaber es kann keine Binärdaten speichern und rsync --link-dest- es generiert harte Links, die im Archiv unbrauchbar sind.

PPS In meinem Fall kann die Änderungszeit nicht verwendet werden, um zu entscheiden, welche Datei geändert wurde.

Dmitry
quelle
1
Haben Sie sich das Verzeichnis "diff" angesehen? Frage?
Rozcietrzewiacz

Antworten:

7

Mit rsync

Was Sie tun, ist im Wesentlichen eine inkrementelle Sicherung: Ihr Freund (Ihre Sicherung) verfügt bereits über die Originaldateien, und Sie möchten ein Archiv erstellen, das die Dateien enthält, die Sie von diesem Original geändert haben.

Rsync bietet Funktionen für inkrementelle Sicherungen.

cd ORIGINAL_AND_MY_CHANGED
rsync -a -c --compare-dest=../ORIGINAL . ../CHANGES_ONLY
  • -a bedeutet, alle Attribute (Zeiten, Besitz usw.) zu erhalten.
  • -c bedeutet, den Dateiinhalt zu vergleichen und sich nicht auf Datum und Größe zu verlassen.
  • --compare-dest=/some/directorybedeutet, dass Dateien, die unter diesem Verzeichnis und dem Quellbaum identisch sind, nicht kopiert werden. Beachten Sie, dass der Pfad relativ zum Zielverzeichnis ist.

Rsync kopiert alle Verzeichnisse, auch wenn dort keine Dateien landen. Führen Sie Folgendes aus, um diese leeren Verzeichnisse zu entfernen find -depth CHANGES_ONLY -type d -empty -delete(oder führen Sie sie aus, wenn Sie findkein -deleteund -emptyhaben find -depth CHANGES_ONLY -exec rmdir {} + 2>/dev/null).

Dann machen Sie das Archiv aus dem CHANGES_ONLYVerzeichnis.

Der Fußgängerweg

Durchsuchen Sie das Verzeichnis mit Ihrer Datei. Überspringen Sie Dateien, die mit dem Original identisch sind. Erstellen Sie nach Bedarf Verzeichnisse im Ziel. Kopieren Sie geänderte Dateien.

cd ORIGINAL_AND_MY_CHANGES
find . \! -type d -exec sh -c '
  for x; do
    if cmp -s "$x" "../ORIGINAL/$x"; then continue; fi
    [ -d "../CHANGES_ONLY/$x" ] || mkdir -p "../CHANGES_ONLY/${%/*}"
    cp -p "$x" "../CHANGES_ONLY/$x"
  done
' {} +
Gilles 'SO - hör auf böse zu sein'
quelle
Es ist sogar eine bessere Lösung als die von enzotib, da ich MY_CHANGES in die Quellcodeverwaltung einbinden und diese Änderungen aktualisieren / verfolgen kann (wenn ich die Batch-Datei von rsync unter Quellcodeverwaltung aktualisiere, kann ich nicht sehen, welche Dateien geändert wurden)
Dmitry
@Dmitry Wenn Sie die Quellcodeverwaltung verwenden, können Sie Import / Track einfügen ORIGINALund ORIGINAL_AND_MY_CHANGESeinen Zweig erstellen . Dann finden Sie es CHANGESmit einem scm-Befehl heraus.
Gilles 'SO - hör auf böse zu sein'
In meinem Fall handelt ORIGINALes sich um Android-Plattformquellen (3 GB, 126000 Dateien). Selbst das Ausführen von rsync dauert ca. 15-20 Minuten. Ich denke, dass das Hinzufügen all dieser Dinge unter Quellcodeverwaltung zu viel Platz und Zeit in Anspruch nehmen wird.
Dmitry
@Dmitry Damit ist es dann erledigt. Wenn es sich um Android-Quellen handelt, verwenden Sie Repo und Git. Arbeiten Sie an Ihrer eigenen Niederlassung. Es ist schon schwer genug, diejenigen mit Versionskontrolle zu verwalten. Ich schaudere, wenn ich darüber nachdenke, wie es ohne sie sein könnte. Glücklicherweise ist git sehr gut darin, lokale Niederlassungen zu verwalten.
Gilles 'SO - hör auf böse zu sein'
Leider handelt es sich um eine benutzerdefinierte Android-Quelle ohne Repo / Git-Repositories.
Dmitry
5

Der Befehl

rsync --only-write-batch=FILE $other_options ORIGINAL_AND_MY_CHANGES/ ORIGINAL/

würde eine Batch-DATEI erstellen, die die erforderlichen Änderungen enthält (ohne etwas zu ändern).

Der Patch kann an einer anderen Stelle angewendet werden, an der Sie die Batch-Datei mit nehmen

rsync --read-batch=FILE ORIGINAL/
Enzotib
quelle