¿Cómo guardo los archivos modificados?

8

Tengo dos carpetas:

  • ORIGINAL/
  • ORIGINAL_AND_MY_CHANGES /

Mi amigo tiene una copia de ORIGINAL /. Me gustaría generar MY_CHANGES.tgz: debe contener solo archivos nuevos / modificados de ORIGINAL_AND_MY_CHANGES / en comparación con ORIGINAL /. Entonces mi amigo puede descomprimirlo en su copia de ORIGINAL / y obtener ORIGINAL_AND_MY_CHANGES /. ¿Cómo puedo hacer esto?

PD: Lo intenté diffpero no puede guardar datos binarios y rsync --link-destgenera enlaces duros que son inútiles en el archivo.

PPS En mi caso, el tiempo de modificación no se puede usar para decidir qué archivo se cambió.

Dmitry
fuente
1
¿Viste el directorio "diff"? ¿pregunta?
rozcietrzewiacz

Respuestas:

7

Con rsync

Lo que está haciendo es esencialmente una copia de seguridad incremental: su amigo (su copia de seguridad) ya tiene los archivos originales y desea crear un archivo que contenga los archivos que ha cambiado de ese original.

Rsync tiene características para copias de seguridad incrementales.

cd ORIGINAL_AND_MY_CHANGED
rsync -a -c --compare-dest=../ORIGINAL . ../CHANGES_ONLY
  • -a significa preservar todos los atributos (tiempos, propiedad, etc.).
  • -c significa comparar el contenido del archivo y no depender de la fecha y el tamaño.
  • --compare-dest=/some/directorysignifica que los archivos que son idénticos en ese directorio y el árbol de origen no se copian. Tenga en cuenta que la ruta es relativa al directorio de destino.

Rsync copia todos los directorios, incluso si no hay archivos terminados allí. Para deshacerse de estos directorios vacíos, ejecute find -depth CHANGES_ONLY -type d -empty -delete(o si findno tiene -deletey -empty, ejecute find -depth CHANGES_ONLY -exec rmdir {} + 2>/dev/null).

Luego haga el archivo desde el CHANGES_ONLYdirectorio.

El camino peatonal

Recorre el directorio con tu archivo. Omita archivos que sean idénticos al original. Cree directorios en el destino según sea necesario. Copiar archivos modificados.

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- deja de ser malvado'
fuente
Es una solución aún mejor que la de enzotib porque puedo poner MY_CHANGES en el control de fuente y actualizar / rastrear estos cambios (si actualizo el archivo por lotes de rsync bajo control de fuente, será imposible ver qué archivos se cambiaron)
Dmitry
@Dmitry Si está utilizando el control de origen, ¿por qué no colocar importación / seguimiento ORIGINALy hacer ORIGINAL_AND_MY_CHANGESuna bifurcación? Luego CHANGESdescúbrelo con un comando scm.
Gilles 'SO- deja de ser malvado'
En mi caso ORIGINAL, son las fuentes de la plataforma Android (3GB, 126000 archivos). Incluso ejecutar rsync tarda ~ 15-20 minutos. Creo que agregar todo esto bajo el control de la fuente tomará demasiado espacio y tiempo.
Dmitry el
@Dmitry Eso lo resuelve entonces. Si se trata de fuentes de Android, use repo y git. Trabaja en tu propia sucursal. Ya es bastante difícil administrar aquellos con control de versiones, me estremezco al pensar cómo sería sin él. Afortunadamente, git es muy bueno en la gestión de sucursales locales.
Gilles 'SO- deja de ser malvado'
Desafortunadamente, es una fuente de Android personalizada sin ningún repositorio de repositorio / git.
Dmitry el
5

El comando

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

produciría un ARCHIVO por lotes que contiene los cambios necesarios (sin modificar nada).

El parche podría aplicarse en otro sitio, donde toma el ARCHIVO por lotes, con

rsync --read-batch=FILE ORIGINAL/
enzotib
fuente