Comment enregistrer les fichiers modifiés?

8

J'ai deux dossiers:

  • ORIGINAL/
  • ORIGINAL_AND_MY_CHANGES /

Mon ami a une copie de ORIGINAL /. Je voudrais générer MY_CHANGES.tgz - il ne doit contenir que des fichiers nouveaux / modifiés depuis ORIGINAL_AND_MY_CHANGES / par rapport à ORIGINAL /. Mon ami peut donc le déballer dans sa copie de ORIGINAL / et obtenir ORIGINAL_AND_MY_CHANGES /. Comment puis-je faire ceci?

PS J'ai essayé diffmais il ne peut pas enregistrer de données binaires et rsync --link-dest- il génère des liens durs qui sont inutiles dans l'archive.

PPS Dans mon cas, l'heure de modification ne peut pas être utilisée pour décider quel fichier a été modifié.

Dmitry
la source
1
Avez-vous consulté le répertoire «diff»? question?
rozcietrzewiacz

Réponses:

7

Avec rsync

Ce que vous faites est essentiellement une sauvegarde incrémentielle: votre ami (votre sauvegarde) a déjà les fichiers d'origine et vous souhaitez créer une archive contenant les fichiers que vous avez modifiés à partir de cet original.

Rsync possède des fonctionnalités pour les sauvegardes incrémentielles.

cd ORIGINAL_AND_MY_CHANGED
rsync -a -c --compare-dest=../ORIGINAL . ../CHANGES_ONLY
  • -a moyens de conserver tous les attributs (temps, propriété, etc.).
  • -c moyen de comparer le contenu du fichier et de ne pas compter sur la date et la taille.
  • --compare-dest=/some/directorysignifie que les fichiers identiques dans ce répertoire et l'arborescence source ne sont pas copiés. Notez que le chemin est relatif au répertoire de destination.

Rsync copie tous les répertoires, même si aucun fichier n'y arrive. Pour vous débarrasser de ces répertoires vides, exécutez find -depth CHANGES_ONLY -type d -empty -delete(ou si votre findn'a pas -deleteet -emptyexécutez find -depth CHANGES_ONLY -exec rmdir {} + 2>/dev/null).

Faites ensuite l'archive à partir du CHANGES_ONLYrépertoire.

La voie piétonne

Parcourez le répertoire avec votre fichier. Ignorez les fichiers identiques à l'original. Créez des répertoires dans la cible si nécessaire. Copiez les fichiers modifiés.

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- arrête d'être méchant'
la source
C'est une meilleure solution que enzotib car je peux mettre MY_CHANGES dans le contrôle de source et mettre à jour / suivre ces changements (si je mets à jour le fichier de commandes de rsync sous contrôle de source, il sera impossible de voir quels fichiers ont été modifiés)
Dmitry
@Dmitry Si vous utilisez le contrôle de code source, pourquoi ne pas mettre import / track ORIGINALet créer ORIGINAL_AND_MY_CHANGESune branche? Découvrez ensuite CHANGESavec une commande scm.
Gilles 'SO- arrête d'être méchant'
Dans mon cas, ORIGINALce sont les sources de la plateforme Android (3 Go, 126 000 fichiers). Même l'exécution de rsync prend environ 15-20 minutes. Je pense que l'ajout de tout cela sous contrôle de source prendra trop de temps et d'espace.
Dmitry
@Dmitry Cela règle alors. S'il s'agit de sources Android, utilisez repo et git. Travaillez sur votre propre branche. C'est déjà assez difficile de gérer ceux avec le contrôle de version, je frissonne de penser à ce que cela pourrait être sans. Heureusement, git est très bon pour gérer les succursales locales.
Gilles 'SO- arrête d'être méchant'
Malheureusement, il s'agit d'une source Android personnalisée sans référentiel repo / git.
Dmitry
5

La commande

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

produirait un FICHIER de lot contenant les modifications requises (sans rien modifier).

Le correctif pourrait être appliqué sur un autre site, où vous prenez le fichier FICHIER, avec

rsync --read-batch=FILE ORIGINAL/
enzotib
la source